Browse Source

Merge branch 'develop' into develop

pull/5309/head
Evan 6 years ago committed by GitHub
parent
commit
1dbb45752f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .dockerignore
  2. 3
      .travis.yml
  3. 24
      Dockerfile
  4. 35
      cmd/hook.go
  5. 3
      cmd/serv.go
  6. 12
      conf/locale/locale_cs-CZ.ini
  7. 16
      conf/locale/locale_de-DE.ini
  8. 2
      conf/locale/locale_en-US.ini
  9. 2
      conf/locale/locale_es-ES.ini
  10. 2
      conf/locale/locale_fi-FI.ini
  11. 106
      conf/locale/locale_it-IT.ini
  12. 14
      conf/locale/locale_ko-KR.ini
  13. 10
      conf/locale/locale_pl-PL.ini
  14. 2
      conf/locale/locale_sr-SP.ini
  15. 2
      conf/locale/locale_uk-UA.ini
  16. 70
      conf/locale/locale_zh-TW.ini
  17. 10
      docker/build.sh
  18. 9
      docker/finalize.sh
  19. 3
      gogs.go
  20. 2
      models/attachment.go
  21. 17
      models/comment.go
  22. 2
      models/errors/errors.go
  23. 8
      models/issue.go
  24. 4
      models/issue_label.go
  25. 2
      models/migrations/migrations.go
  26. 8
      models/milestone.go
  27. 2
      models/mirror.go
  28. 21
      models/models.go
  29. 2
      models/org.go
  30. 20
      models/org_team.go
  31. 9
      models/pull.go
  32. 2
      models/release.go
  33. 12
      models/repo.go
  34. 4
      models/repo_branch.go
  35. 2
      models/repo_collaboration.go
  36. 229
      models/repo_editor.go
  37. 5
      models/ssh_key.go
  38. 4
      models/user.go
  39. 4
      models/user_mail.go
  40. 2
      models/webhook.go
  41. 80
      pkg/bindata/bindata.go
  42. 4
      pkg/context/context.go
  43. 5
      pkg/markup/markup.go
  44. 3
      public/css/gogs.css
  45. 15
      public/js/gogs.js
  46. 3
      public/less/_repository.less
  47. 18
      routes/repo/commit.go
  48. 41
      routes/repo/editor.go
  49. 38
      routes/repo/http.go
  50. 4
      routes/repo/pull.go
  51. 1
      routes/repo/setting.go
  52. 4
      routes/user/auth.go
  53. 7
      scripts/systemd/gogs.service
  54. 2
      templates/.VERSION
  55. 8
      templates/base/footer.tmpl
  56. 4
      templates/base/head.tmpl
  57. 54
      templates/home.tmpl
  58. 2
      templates/mail/auth/activate.tmpl
  59. 2
      templates/mail/auth/activate_email.tmpl
  60. 2
      templates/mail/auth/register_notify.tmpl
  61. 2
      templates/mail/auth/reset_passwd.tmpl
  62. 2
      templates/org/home.tmpl
  63. 2
      templates/repo/create.tmpl
  64. 2
      templates/repo/header.tmpl
  65. 2
      templates/repo/issue/labels.tmpl
  66. 10
      templates/repo/issue/view_content.tmpl
  67. 2
      templates/repo/release/new.tmpl
  68. 2
      templates/repo/user_cards.tmpl
  69. 2
      templates/user/profile.tmpl
  70. 2
      vendor/github.com/gogs/git-module/git.go
  71. 9
      vendor/github.com/gogs/git-module/repo.go
  72. 2
      vendor/github.com/gogs/git-module/repo_commit.go
  73. 4
      vendor/github.com/gogs/git-module/repo_tag.go
  74. 6
      vendor/vendor.json

2
.dockerignore

@ -1,5 +1,3 @@
.git
.git/**
packager
packager/**
scripts

3
.travis.yml

@ -10,9 +10,6 @@ before_install:
- sudo apt-get update -qq
- sudo apt-get install -y libpam-dev
env:
- GO15VENDOREXPERIMENT=1
script:
- go build -v -tags "pam"
- go test -v -cover -race ./...

24
Dockerfile

@ -1,7 +1,13 @@
FROM alpine:3.5
FROM golang:alpine AS binarybuilder
# Install build deps
RUN apk --no-cache --no-progress add --virtual build-deps build-base git linux-pam-dev
WORKDIR /go/src/github.com/gogs/gogs
COPY . .
RUN make build TAGS="sqlite cert pam"
FROM alpine:latest
# Install system utils & Gogs runtime dependencies
ADD https://github.com/tianon/gosu/releases/download/1.9/gosu-amd64 /usr/sbin/gosu
ADD https://github.com/tianon/gosu/releases/download/1.10/gosu-amd64 /usr/sbin/gosu
RUN chmod +x /usr/sbin/gosu \
&& echo http://dl-2.alpinelinux.org/alpine/edge/community/ >> /etc/apk/repositories \
&& apk --no-cache --no-progress add \
@ -20,16 +26,14 @@ ENV GOGS_CUSTOM /data/gogs
# Configure LibC Name Service
COPY docker/nsswitch.conf /etc/nsswitch.conf
COPY docker /app/gogs/docker
COPY templates /app/gogs/templates
COPY public /app/gogs/public
WORKDIR /app/gogs/build
COPY . .
WORKDIR /app/gogs
COPY docker ./docker
COPY templates ./templates
COPY public ./public
COPY --from=binarybuilder /go/src/github.com/gogs/gogs/gogs .
RUN ./docker/build-go.sh \
&& ./docker/build.sh \
&& ./docker/finalize.sh
RUN ./docker/finalize.sh
# Configure Docker Container
VOLUME ["/data"]

35
cmd/hook.go

@ -27,7 +27,6 @@ import (
"github.com/gogs/gogs/pkg/mailer"
"github.com/gogs/gogs/pkg/setting"
"github.com/gogs/gogs/pkg/template"
http "github.com/gogs/gogs/routes/repo"
)
var (
@ -71,7 +70,7 @@ func runHookPreReceive(c *cli.Context) error {
}
setup(c, "hooks/pre-receive.log", true)
isWiki := strings.Contains(os.Getenv(http.ENV_REPO_CUSTOM_HOOKS_PATH), ".wiki.git/")
isWiki := strings.Contains(os.Getenv(models.ENV_REPO_CUSTOM_HOOKS_PATH), ".wiki.git/")
buf := bytes.NewBuffer(nil)
scanner := bufio.NewScanner(os.Stdin)
@ -92,7 +91,7 @@ func runHookPreReceive(c *cli.Context) error {
branchName := strings.TrimPrefix(string(fields[2]), git.BRANCH_PREFIX)
// Branch protection
repoID := com.StrTo(os.Getenv(http.ENV_REPO_ID)).MustInt64()
repoID := com.StrTo(os.Getenv(models.ENV_REPO_ID)).MustInt64()
protectBranch, err := models.GetProtectBranchOfRepoByName(repoID, branchName)
if err != nil {
if errors.IsErrBranchNotExist(err) {
@ -108,7 +107,7 @@ func runHookPreReceive(c *cli.Context) error {
bypassRequirePullRequest := false
// Check if user is in whitelist when enabled
userID := com.StrTo(os.Getenv(http.ENV_AUTH_USER_ID)).MustInt64()
userID := com.StrTo(os.Getenv(models.ENV_AUTH_USER_ID)).MustInt64()
if protectBranch.EnableWhitelist {
if !models.IsUserInProtectBranchWhitelist(repoID, userID, branchName) {
fail(fmt.Sprintf("Branch '%s' is protected and you are not in the push whitelist", branchName), "")
@ -129,7 +128,7 @@ func runHookPreReceive(c *cli.Context) error {
// Check force push
output, err := git.NewCommand("rev-list", "--max-count=1", oldCommitID, "^"+newCommitID).
RunInDir(models.RepoPath(os.Getenv(http.ENV_REPO_OWNER_NAME), os.Getenv(http.ENV_REPO_NAME)))
RunInDir(models.RepoPath(os.Getenv(models.ENV_REPO_OWNER_NAME), os.Getenv(models.ENV_REPO_NAME)))
if err != nil {
fail("Internal error", "Fail to detect force push: %v", err)
} else if len(output) > 0 {
@ -137,7 +136,7 @@ func runHookPreReceive(c *cli.Context) error {
}
}
customHooksPath := filepath.Join(os.Getenv(http.ENV_REPO_CUSTOM_HOOKS_PATH), "pre-receive")
customHooksPath := filepath.Join(os.Getenv(models.ENV_REPO_CUSTOM_HOOKS_PATH), "pre-receive")
if !com.IsFile(customHooksPath) {
return nil
}
@ -148,7 +147,7 @@ func runHookPreReceive(c *cli.Context) error {
} else {
hookCmd = exec.Command(customHooksPath)
}
hookCmd.Dir = models.RepoPath(os.Getenv(http.ENV_REPO_OWNER_NAME), os.Getenv(http.ENV_REPO_NAME))
hookCmd.Dir = models.RepoPath(os.Getenv(models.ENV_REPO_OWNER_NAME), os.Getenv(models.ENV_REPO_NAME))
hookCmd.Stdout = os.Stdout
hookCmd.Stdin = buf
hookCmd.Stderr = os.Stderr
@ -171,7 +170,7 @@ func runHookUpdate(c *cli.Context) error {
fail("First argument 'refName' is empty", "First argument 'refName' is empty")
}
customHooksPath := filepath.Join(os.Getenv(http.ENV_REPO_CUSTOM_HOOKS_PATH), "update")
customHooksPath := filepath.Join(os.Getenv(models.ENV_REPO_CUSTOM_HOOKS_PATH), "update")
if !com.IsFile(customHooksPath) {
return nil
}
@ -182,7 +181,7 @@ func runHookUpdate(c *cli.Context) error {
} else {
hookCmd = exec.Command(customHooksPath, args...)
}
hookCmd.Dir = models.RepoPath(os.Getenv(http.ENV_REPO_OWNER_NAME), os.Getenv(http.ENV_REPO_NAME))
hookCmd.Dir = models.RepoPath(os.Getenv(models.ENV_REPO_OWNER_NAME), os.Getenv(models.ENV_REPO_NAME))
hookCmd.Stdout = os.Stdout
hookCmd.Stdin = os.Stdin
hookCmd.Stderr = os.Stderr
@ -205,7 +204,7 @@ func runHookPostReceive(c *cli.Context) error {
mailer.InitMailRender(path.Join(setting.StaticRootPath, "templates/mail"),
path.Join(setting.CustomPath, "templates/mail"), template.NewFuncMap())
isWiki := strings.Contains(os.Getenv(http.ENV_REPO_CUSTOM_HOOKS_PATH), ".wiki.git/")
isWiki := strings.Contains(os.Getenv(models.ENV_REPO_CUSTOM_HOOKS_PATH), ".wiki.git/")
buf := bytes.NewBuffer(nil)
scanner := bufio.NewScanner(os.Stdin)
@ -227,10 +226,10 @@ func runHookPostReceive(c *cli.Context) error {
OldCommitID: string(fields[0]),
NewCommitID: string(fields[1]),
RefFullName: string(fields[2]),
PusherID: com.StrTo(os.Getenv(http.ENV_AUTH_USER_ID)).MustInt64(),
PusherName: os.Getenv(http.ENV_AUTH_USER_NAME),
RepoUserName: os.Getenv(http.ENV_REPO_OWNER_NAME),
RepoName: os.Getenv(http.ENV_REPO_NAME),
PusherID: com.StrTo(os.Getenv(models.ENV_AUTH_USER_ID)).MustInt64(),
PusherName: os.Getenv(models.ENV_AUTH_USER_NAME),
RepoUserName: os.Getenv(models.ENV_REPO_OWNER_NAME),
RepoName: os.Getenv(models.ENV_REPO_NAME),
}
if err := models.PushUpdate(options); err != nil {
log.Error(2, "PushUpdate: %v", err)
@ -239,8 +238,8 @@ func runHookPostReceive(c *cli.Context) error {
// Ask for running deliver hook and test pull request tasks
reqURL := setting.LocalURL + options.RepoUserName + "/" + options.RepoName + "/tasks/trigger?branch=" +
template.EscapePound(strings.TrimPrefix(options.RefFullName, git.BRANCH_PREFIX)) +
"&secret=" + os.Getenv(http.ENV_REPO_OWNER_SALT_MD5) +
"&pusher=" + os.Getenv(http.ENV_AUTH_USER_ID)
"&secret=" + os.Getenv(models.ENV_REPO_OWNER_SALT_MD5) +
"&pusher=" + os.Getenv(models.ENV_AUTH_USER_ID)
log.Trace("Trigger task: %s", reqURL)
resp, err := httplib.Head(reqURL).SetTLSClientConfig(&tls.Config{
@ -256,7 +255,7 @@ func runHookPostReceive(c *cli.Context) error {
}
}
customHooksPath := filepath.Join(os.Getenv(http.ENV_REPO_CUSTOM_HOOKS_PATH), "post-receive")
customHooksPath := filepath.Join(os.Getenv(models.ENV_REPO_CUSTOM_HOOKS_PATH), "post-receive")
if !com.IsFile(customHooksPath) {
return nil
}
@ -267,7 +266,7 @@ func runHookPostReceive(c *cli.Context) error {
} else {
hookCmd = exec.Command(customHooksPath)
}
hookCmd.Dir = models.RepoPath(os.Getenv(http.ENV_REPO_OWNER_NAME), os.Getenv(http.ENV_REPO_NAME))
hookCmd.Dir = models.RepoPath(os.Getenv(models.ENV_REPO_OWNER_NAME), os.Getenv(models.ENV_REPO_NAME))
hookCmd.Stdout = os.Stdout
hookCmd.Stdin = buf
hookCmd.Stderr = os.Stderr

3
cmd/serv.go

@ -19,7 +19,6 @@ import (
"github.com/gogs/gogs/models"
"github.com/gogs/gogs/models/errors"
"github.com/gogs/gogs/pkg/setting"
http "github.com/gogs/gogs/routes/repo"
)
const (
@ -252,7 +251,7 @@ func runServ(c *cli.Context) error {
gitCmd = exec.Command(verb, repoFullName)
}
if requestMode == models.ACCESS_MODE_WRITE {
gitCmd.Env = append(os.Environ(), http.ComposeHookEnvs(http.ComposeHookEnvsOptions{
gitCmd.Env = append(os.Environ(), models.ComposeHookEnvs(models.ComposeHookEnvsOptions{
AuthUser: user,
OwnerName: owner.Name,
OwnerSalt: owner.Salt,

12
conf/locale/locale_cs-CZ.ini

@ -39,7 +39,7 @@ your_profile=Váš profil
your_settings=Vaše nastavení
activities=Aktivity
pull_requests=Pull Requesty
pull_requests=Požadavky na natažení
issues=Úkoly
cancel=Zrušit
@ -72,7 +72,7 @@ run_user=Účet pro spouštění
run_user_helper=Tento uživatel musí mít přístup do kořenového adresáře repositářů a právo spustit Gogs.
domain=Doména
domain_helper=Toto ovlivňuje URL klonů skrze SSH.
ssh_port=SSH port
ssh_port=Port SSH
ssh_port_helper=Číslo portu, které používá váš SSH server. Nechte jej prázdné pro vypnutí používání SSH.
use_builtin_ssh_server=Použít vestavěný SSH server
use_builtin_ssh_server_popup=Pro Git operace spustit vestavěný SSH server, aby byl rozpoznán od systémové SSH služby.
@ -319,7 +319,7 @@ add_email_success=Vaše nová e-mailová adresa byla přidána.
manage_ssh_keys=Správa SSH klíčů
add_key=Přidat klíč
ssh_desc=Toto je seznam SSH klíčů vašeho účtu. Tyto klíče umožňují plný přístup k vašim repositářům, proto je velmi důležité, abyste jste si byli jistí, že jsou skutečně vaše.
ssh_desc=Toto je seznam SSH klíčů vašeho účtu. Jelikož SSH klíče umožňují komukoliv plný přístup k vašim repositářům, je velmi důležité, abyste si byli jistí, že jsou skutečně vaše.
ssh_helper=<strong>Nevíte jak?</strong> Podívejte se do příručky GitHubu jak si <a href="%s">vytvořit vlastní SSH klíč</a>, nebo na <a href="%s">řešení častých problémů</a>, na které můžete narazit při používání SSH.
add_new_key=Přidat SSH klíč
ssh_key_been_used=Obsah veřejného klíče byl použit.
@ -329,8 +329,8 @@ key_content=Obsah
add_key_success=Byl přidán nový SSH klíč '%s'!
delete_key=Smazat
ssh_key_deletion=Smazání SSH klíče
ssh_key_deletion_desc=Smazání tohoto SSH klíče odstraní všechny související přístupy k vašemu účtu. Chcete pokračovat?
ssh_key_deletion_success=SSH klíč úspěšně odstraněn!
ssh_key_deletion_desc=Smazání tohoto klíče SSH odstraní všechny související přístupy k vašemu účtu. Chcete pokračovat?
ssh_key_deletion_success=SSH klíč byl úspěšně smazán!
add_on=Přidán dne
last_used=Naposledy použit dne
no_activity=Žádná aktuální aktivita
@ -846,7 +846,7 @@ settings.slack_channel=Kanál
settings.deploy_keys=Klíče pro nasazení
settings.deploy_keys_helper=<b>Přichycen při činu!</b> Pokud chcete přidat osobní veřejné klíče, zadejte je prosím v <a href="%s%s">nastavení vašeho účtu</a>.
settings.add_deploy_key=Přidat klíč pro nasazení
settings.deploy_key_desc=Klíče pro nasazení mají pouze přístup ke čtení. Nejsou stejné jako osobní SSH klíče.
settings.deploy_key_desc=Klíče pro nasazení mají pouze přístup ke čtení. Nejsou stejné jako SSH klíče osobního účtu.
settings.no_deploy_keys=Žádné klíče pro nasazení nebyly ještě přidány.
settings.title=Název
settings.deploy_key_content=Obsah

16
conf/locale/locale_de-DE.ini

@ -151,8 +151,8 @@ register_hepler_msg=Haben Sie bereits ein Konto? Jetzt anmelden!
social_register_hepler_msg=Haben Sie bereits ein Konto? Jetzt verknüpfen!
disable_register_prompt=Es tut uns leid, die Registrierung wurde deaktiviert. Bitte wenden Sie sich an den Administrator.
disable_register_mail=Es tut uns leid, die Bestätigung der Registrierungs-E-Mail wurde deaktiviert.
auth_source=Authentication Source
local=Local
auth_source=Authentifizierungsquelle
local=Lokalisierung
remember_me=Angemeldet bleiben
forgot_password=Passwort vergessen
forget_password=Passwort vergessen?
@ -231,7 +231,7 @@ org_name_been_taken=Organisationsname ist bereits vergeben.
team_name_been_taken=Teamname ist bereits vergeben.
email_been_used=E-Mail-Adresse wird bereits verwendet.
username_password_incorrect=Benutzername oder Passwort ist nicht korrekt.
auth_source_mismatch=The authentication source selected is not associated with the user.
auth_source_mismatch=Die ausgewählte Authentifizierungsquelle ist dem Benutzer nicht zugeordnet.
enterred_invalid_repo_name=Bitte achten Sie darauf, dass der von Ihnen eingegebene Repository-Name korrekt ist.
enterred_invalid_owner_name=Bitte achten Sie darauf, dass der eingegebene Name des Besitzers korrekt ist.
enterred_invalid_password=Bitte achten Sie darauf, dass das eingegebene Passwort richtig ist.
@ -351,7 +351,7 @@ two_factor_or_enter_secret=Oder geben Sie Ihren Geheim-Code ein:
two_factor_then_enter_passcode=Geben Sie die PIN ein:
two_factor_verify=Bestätigen
two_factor_invalid_passcode=Die eingegebene PIN ist ungültig. Bitte versuchen Sie es erneut!
two_factor_reused_passcode=The passcode you entered has already been used, please try another one!
two_factor_reused_passcode=Der von dir eingegebene Passcode wurde bereits verwendet, bitte probiere einen anderen!
two_factor_enable_error=Einschalten der Zwei-Faktor-Authentifizierung ist fehlgeschlagen: %v
two_factor_enable_success=Die Zwei-Faktor-Authentifizierung wurde für Ihr Konto erfolgreich aktiviert!
two_factor_recovery_codes_title=Zwei-Faktor-Authentifizierung-Wiederherstellungscodes
@ -765,7 +765,7 @@ settings.wiki_deletion_success=Repository Wiki Daten erfolgreich gelöscht.
settings.delete=Dieses Repository löschen
settings.delete_desc=Wenn dieses Repository gelöscht wurde, gibt es keinen Weg zurück. Bitte seien Sie vorsichtig.
settings.delete_notices_1=- Diese Operation kann <strong>NICHT</strong> rückgängig gemacht werden.
settings.delete_notices_2=- This operation will permanently delete everything in this repository, including Git data, issues, comments and collaborator access.
settings.delete_notices_2=- Die Operation wird alles, was mit diesem Git-Repository verbunden ist, dauerhaft löschen, inklusive der Daten, Issues, Kommentare und Zugriffsrechte von Mitarbeitern.
settings.delete_notices_fork_1=- Nach dem Löschen werden alle Forks unabhängig.
settings.deletion_success=Repository wurde erfolgreich gelöscht!
settings.update_settings_success=Repository-Optionen aktualisiert.
@ -1091,7 +1091,7 @@ repos.stars=Favoriten
repos.issues=Issues
repos.size=Größe
auths.auth_sources=Authentication Sources
auths.auth_sources=Authentifizierungsquelle
auths.new=Neue Quelle hinzufügen
auths.name=Name
auths.type=Typ
@ -1166,7 +1166,7 @@ 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=Rewrite authorized_keys At Start
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
@ -1304,7 +1304,7 @@ delete_branch=hat Branch <code>%[2]s</code> in <a href="%[1]s">%[3]s</a> gelösc
push_tag=hat Tag <a href="%s/src/%s">%[2]s</a> auf <a href="%[1]s">%[3]s</a> gepusht
delete_tag=hat Tag <code>%[2]s</code> in <a href="%[1]s">%[3]s</a> gelöscht
fork_repo=hat das Repository nach <a href="%s">%s</a> geforkt
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_push=hat auf <a href="%[1]s/src/%[2]s">%[3]s</a> in <a href="%[1]s">%[4]s</a> gepusht
mirror_sync_create=synced new reference <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a> from mirror
mirror_sync_delete=synced and deleted reference <code>%[2]s</code> at <a href="%[1]s">%[3]s</a> from mirror

2
conf/locale/locale_en-US.ini

@ -520,6 +520,7 @@ editor.file_changed_while_editing = File content has been changed since you star
editor.file_already_exists = A file with name '%s' already exists in this repository.
editor.no_changes_to_show = There are no changes to show.
editor.fail_to_update_file = Failed to update/create file '%s' with error: %v
editor.fail_to_delete_file = Failed to delete file '%s' with error: %v
editor.add_subdir = Add subdirectory...
editor.unable_to_upload_files = Failed to upload files to '%s' with error: %v
editor.upload_files_to_dir = Upload files to '%s'
@ -640,6 +641,7 @@ pulls.cannot_auto_merge_desc = This pull request can't be merged automatically b
pulls.cannot_auto_merge_helper = Please merge manually in order to resolve the conflicts.
pulls.create_merge_commit = Create a merge commit
pulls.rebase_before_merging = Rebase before merging
pulls.commit_description = Commit Description
pulls.merge_pull_request = Merge Pull Request
pulls.open_unmerged_pull_exists = `You can't perform reopen operation because there is already an open pull request (#%d) from same repository with same merge information and is waiting for merging.`
pulls.delete_branch = Delete Branch

2
conf/locale/locale_es-ES.ini

@ -1298,7 +1298,7 @@ comment_issue=`comentó en la incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`creado pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`cerró el pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`reabrió el pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
merge_pull_request=`fusionado pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
merge_pull_request=`fusionó el pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
create_branch=nueva rama <a href="%[1]s/src/%[2]s">%[3]s</a> creada en <a href="%[1]s">%[4]s</a>
delete_branch=borrada rama <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
push_tag=hizo push del tag <a href="%s/src/%s">%[2]s</a> a <a href="%[1]s">%[3]s</a>

2
conf/locale/locale_fi-FI.ini

@ -768,7 +768,7 @@ settings.delete_notices_1=- Tätä toimintoa <strong>EI VOI</strong> peruuttaa m
settings.delete_notices_2=- This operation will permanently delete everything in this repository, including Git data, issues, comments and collaborator access.
settings.delete_notices_fork_1=- Kaikki haarat muuttuvat itsenäisiksi poiston jälkeen.
settings.deletion_success=Repo on poistettu onnistuneesti!
settings.update_settings_success=Repom asetukset on päivitetty onnistuneesti.
settings.update_settings_success=Repon asetukset on päivitetty onnistuneesti.
settings.transfer_owner=Uusi omistaja
settings.make_transfer=Tee siirto
settings.transfer_succeed=Arkiston omistusoikeus on siirretty onnistuneesti.

106
conf/locale/locale_it-IT.ini

@ -151,7 +151,7 @@ register_hepler_msg=Hai già un account? Accedi ora!
social_register_hepler_msg=Hai già un account? Associalo ora!
disable_register_prompt=Siamo spiacenti, registrazione è stata disabilitata. Si prega di contattare l'amministratore del sito.
disable_register_mail=Siamo spiacenti, la conferma di registrazione via Mail è stata disattivata.
auth_source=Authentication Source
auth_source=Fonte di autenticazione
local=Local
remember_me=Ricordami
forgot_password=Password dimenticata
@ -172,7 +172,7 @@ password_too_short=La lunghezza della password non può essere meno 6 caratteri.
non_local_account=Gli account non locali non possono modificare le password tramite Gogs.
login_two_factor=Autenticazione in Due Passaggi
login_two_factor_passcode=Authentication Passcode
login_two_factor_passcode=Codice di autenticazione
login_two_factor_enter_recovery_code=Inserisci il codice di recupero dell'Autenticazione a due Fattori
login_two_factor_recovery=Two-factor Recovery
login_two_factor_recovery_code=Recupera il codice
@ -267,7 +267,7 @@ profile=Profilo
password=Password
avatar=Avatar
ssh_keys=Chiavi SSH
security=Security
security=Sicurezza
repos=Repository
orgs=Organizzazioni
applications=Applicazioni
@ -338,30 +338,30 @@ key_state_desc=Hai utilizzato questa chiave negli ultimi 7 giorni
token_state_desc=Questo token e' satato utilizzato negli ultimi 7 giorni
two_factor=Autenticazione in Due Passaggi
two_factor_status=Status:
two_factor_status=Stato:
two_factor_on=Attiva
two_factor_off=Off
two_factor_enable=Enable
two_factor_off=Non attivo
two_factor_enable=Abilita
two_factor_disable=Disattivata
two_factor_view_recovery_codes=View and save <a href="%s%s">your recovery codes</a> in a safe place. You can use them as passcode if you lose access to your authentication application.
two_factor_view_recovery_codes=Visualizza e memorizza i tuoi <a href="%s%s">codici di recupero</a> in un posto sicuro. Puoi utilizzarli come codice di sicurezza se perdi gli accessi all'applicazione di autenticazione.
two_factor_http=For HTTP/HTTPS operations, you are no longer able to use plain username and password. Please create and use <a href="%[1]s%[2]s">Personal Access Token</a> as your credential, e.g. <code>%[3]s</code>.
two_factor_enable_title=Abilita l'autenticazione in due passaggi
two_factor_scan_qr=Please use your authentication application to scan the image:
two_factor_or_enter_secret=Or enter the secret:
two_factor_then_enter_passcode=Then enter passcode:
two_factor_scan_qr=Per favore, utilizza la tua applicazione di autenticazione per scansionare l'immagine:
two_factor_or_enter_secret=O inserisci la chiave segreta:
two_factor_then_enter_passcode=Poi inserisci la chiave di sicurezza:
two_factor_verify=Verifica
two_factor_invalid_passcode=The passcode you entered is not valid, please try again!
two_factor_reused_passcode=The passcode you entered has already been used, please try another one!
two_factor_enable_error=Enable Two-factor authentication failed: %v
two_factor_invalid_passcode=La chiave di sicurezza che hai inserito non è valida, riprova!
two_factor_reused_passcode=La chiave di sicurezza che hai inserito è già stata utilizzata, provane un'altra!
two_factor_enable_error=Impossibile abilitare l'autenticazione a due fattori: %v
two_factor_enable_success=Two-factor authentication has enabled for your account successfully!
two_factor_recovery_codes_title=Two-factor Authentication Recovery Codes
two_factor_recovery_codes_desc=Recovery codes are used when you temporarily lose access to your authentication application. Each recovery code can only be used once, <b>please keep these codes in a safe place</b>.
two_factor_regenerate_recovery_codes=Regenerate Recovery Codes
two_factor_regenerate_recovery_codes_error=Regenerate recovery codes failed: %v
two_factor_regenerate_recovery_codes_success=New recovery codes has been generated successfully!
two_factor_disable_title=Disable Two-factor Authentication
two_factor_disable_desc=Your account security level will decrease after disabled two-factor authentication. Do you want to continue?
two_factor_disable_success=Two-factor authentication has disabled successfully!
two_factor_regenerate_recovery_codes=Rigenera codici di recupero
two_factor_regenerate_recovery_codes_error=Impossibile rigenerare codici di recupero: %v
two_factor_regenerate_recovery_codes_success=I nuovi codici di recupero sono stati generati correttamente!
two_factor_disable_title=Disabilita autenticazione a due fattori
two_factor_disable_desc=Il livello di sicurezza del tuo account diminuirà disabilitando l'autenticazione a due fattori. Vuoi continuare?
two_factor_disable_success=L'autenticazione a due fattori è stata disabilitata!
manage_access_token=Gestisci i Token di Accesso Personale
generate_new_token=Genera Nuovo Token
@ -467,7 +467,7 @@ pulls=Pull Requests
labels=Etichette
milestones=Traguardi
commits=Commit
git_branches=Branches
git_branches=Rami (Branch)
releases=Rilasci
file_raw=Originale
file_history=Cronologia
@ -476,12 +476,12 @@ file_permalink=Permalink
file_too_large=Questo file è troppo grande per essere mostrato
video_not_supported_in_browser=Il tuo browser non supporta i tag "video" di HTML5.
branches.overview=Overview
branches.active_branches=Active Branches
branches.overview=Panoramica
branches.active_branches=Rami (Branch) attivi
branches.stale_branches=Stale Branches
branches.all=All Branches
branches.all=Tutti i rami (branch)
branches.updated_by=Updated %[1]s by %[2]s
branches.change_default_branch=Change Default Branch
branches.change_default_branch=Cambia branch di default
editor.new_file=Nuovo file
editor.upload_file=Carica File
@ -580,8 +580,8 @@ issues.next=Pagina successiva
issues.open_title=Aperto
issues.closed_title=Chiuso
issues.num_comments=%d commenti
issues.commented_at=`commented <a href="#%s">%s</a>`
issues.delete_comment_confirm=Are you sure you want to delete this comment?
issues.commented_at=`ha commentato <a href="#%s">%s</a>`
issues.delete_comment_confirm=Sei sicuro/a di voler eliminare questo commento?
issues.no_content=Non ci sono ancora contenuti.
issues.close_issue=Chiudi
issues.close_comment_issue=Commenta e chiudi
@ -637,7 +637,7 @@ pulls.can_auto_merge_desc=La pull request può essere mergiata automaticamente.
pulls.cannot_auto_merge_desc=Questa pull request non può essere mergiata automaticamente perchè ci sono dei conflitti.
pulls.cannot_auto_merge_helper=Effettua il merge manualmente per risolvere i conflitti.
pulls.create_merge_commit=Create a merge commit
pulls.rebase_before_merging=Rebase before merging
pulls.rebase_before_merging=Effettua un Rebase prima del Merge
pulls.merge_pull_request=Unisci Pull Request
pulls.open_unmerged_pull_exists=`You can't perform reopen operation because there is already an open pull request (#%d) from same repository with same merge information and is waiting for merging.`
pulls.delete_branch=Delete Branch
@ -718,32 +718,32 @@ settings.update_protect_branch_success=Protect options for this branch has been
settings.hooks=Webhooks
settings.githooks=Git Hooks
settings.basic_settings=Impostazioni di Base
settings.mirror_settings=Mirror Settings
settings.sync_mirror=Sync Now
settings.mirror_sync_in_progress=Mirror syncing is in progress, please refresh page in about a minute.
settings.mirror_settings=Impostazioni mirror
settings.sync_mirror=Sincronizza ora
settings.mirror_sync_in_progress=Sincronizzazione del mirror in corso, aggiorna la pagina tra un minuto.
settings.site=Sito Ufficiale
settings.update_settings=Aggiorna Impostazioni
settings.change_reponame_prompt=Questa modifica influirà i link al repository.
settings.advanced_settings=Opzioni avanzate
settings.wiki_desc=Enable wiki system
settings.use_internal_wiki=Use builtin wiki
settings.wiki_desc=Abilita wiki
settings.use_internal_wiki=Usa wiki incorporato
settings.allow_public_wiki_desc=Allow public access to wiki when repository is private
settings.use_external_wiki=Usa Wiki esterno
settings.external_wiki_url=URL Wiki esterno
settings.external_wiki_url_desc=I visitatori verranno reindirizzati all'URL quando cliccano sulla scheda.
settings.issues_desc=Enable issue tracker
settings.use_internal_issue_tracker=Use builtin lightweight issue tracker
settings.issues_desc=Abilita tracking problemi
settings.use_internal_issue_tracker=Utilizza il segnalatore di problemi integrato (molto leggero)
settings.allow_public_issues_desc=Allow public access to issues when repository is private
settings.use_external_issue_tracker=Utilizza gestore di problemi esterno
settings.external_tracker_url=External Issue Tracker URL
settings.external_tracker_url_desc=Visitors will be redirected to URL when they click on the tab.
settings.external_tracker_url=URL di un segnalatore di problemi esterno
settings.external_tracker_url_desc=I visitatori verranno reindirizzati all'URL quando faranno click sulla scheda.
settings.tracker_url_format=Formato URL Gestore Problemi Esterno
settings.tracker_issue_style=External Issue Tracker Naming Style:
settings.tracker_issue_style.numeric=Numeric
settings.tracker_issue_style.alphanumeric=Alphanumeric
settings.tracker_issue_style.numeric=Numerico
settings.tracker_issue_style.alphanumeric=Alfanumerico
settings.tracker_url_format_desc=You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
settings.pulls_desc=Abilita le pull requests per accettare contributi pubblici
settings.pulls.ignore_whitespace=Ignore changes in whitespace
settings.pulls.ignore_whitespace=Ignora cambiamenti di spazi bianchi
settings.pulls.allow_rebase_merge=Allow use rebase to merge commits
settings.danger_zone=Zona Pericolosa
settings.cannot_fork_to_same_owner=You cannot fork a repository to its original owner.
@ -815,19 +815,19 @@ settings.event_send_everything=Ho bisogno di <strong>tutto</strong>.
settings.event_choose=Lasciami scegliere ciò di cui ho bisogno.
settings.event_create=Crea
settings.event_create_desc=Branch, o tag creato
settings.event_delete=Delete
settings.event_delete_desc=Branch or tag deleted
settings.event_delete=Elimina
settings.event_delete_desc=Branch o tag eliminato
settings.event_fork=Forka
settings.event_fork_desc=Repository Forkata
settings.event_push=Push
settings.event_push_desc=Git push in un repository
settings.event_issues=Issues
settings.event_issues=Problemi
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
settings.event_pull_request=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=Versione
settings.event_release_desc=Release published in a repository.
settings.active=Attivo
settings.active_helper=Anche i dettagli riguardanti l'evento che ha innescato l'hook saranno inviati.
@ -898,7 +898,7 @@ release.deletion=Eliminazione Release
release.deletion_desc=Eliminando questa release cancellarai anche i tag Git corrispondenti. Vuoi continuare?
release.deletion_success=La release è stata eliminata con successo!
release.tag_name_already_exist=Un rilascio con questo tag esiste già.
release.tag_name_invalid=Tag name is not valid.
release.tag_name_invalid=Il nome del Tag non è valido.
release.downloads=Download
[org]
@ -922,7 +922,7 @@ team_permission_desc=Quale livello di autorizzazione dovrebbe avere questa squad
form.name_reserved=Il nome organizzazione '%s' è riservato.
form.name_pattern_not_allowed=La struttura del nome dell'organizzazione '%s' non è consentita.
form.team_name_reserved=Team name '%s' is reserved.
form.team_name_reserved=Non puoi utilizzare '%s' come nome del Team.
settings=Impostazioni
settings.options=Opzioni
@ -1089,7 +1089,7 @@ repos.private=Privati
repos.watches=Segue
repos.stars=Voti
repos.issues=Problemi
repos.size=Size
repos.size=Dimensione
auths.auth_sources=Authentication Sources
auths.new=Aggiungi Nuova Origine
@ -1114,7 +1114,7 @@ auths.attribute_username_placeholder=Se vuoto, verrà usato il nome di login del
auths.attribute_name=First Name Attribute
auths.attribute_surname=Attributo Cognome
auths.attribute_mail=Attributo Email
auths.verify_group_membership=Verify group membership
auths.verify_group_membership=Verifica gruppo di appartenenza
auths.group_search_base_dn=Group Search Base DN
auths.group_filter=Group Filter
auths.group_attribute_contain_user_list=Group Attribute Containing List of Users
@ -1144,7 +1144,7 @@ auths.still_in_used=Questo meccanismo di autenticazione è ancora attivo per alc
auths.deletion_success=Il meccanismo di autenticazione è stato eliminato!
auths.login_source_exist=La fonte di autenticazione '%s' esiste già.
config.not_set=(not set)
config.not_set=(non impostata)
config.server_config=Configurazione Server
config.app_name=Nome Applicazione
config.app_ver=Versione Applicazione
@ -1172,17 +1172,17 @@ 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.repo_config=Repository Configuration
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=Disable HTTP Git
config.enable_local_path_migration=Enable Local Path Migration
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=HTTP Configuration
config.http_config=Configurazione HTTP
config.http_access_control_allow_origin=Access Control Allow Origin
config.db_config=Configurazione Database
@ -1258,7 +1258,7 @@ config.git_gc_timeout=Timeout per le operazioni di GC
config.log_config=Configurazione Log
config.log_mode=Modalità
config.log_options=Options
config.log_options=Opzioni
monitor.cron=Incarici di cron
monitor.name=Nome

14
conf/locale/locale_ko-KR.ini

@ -152,7 +152,7 @@ social_register_hepler_msg=계정을 가지고 계신가요? 연결하세요!
disable_register_prompt=죄송합니다, 가입이 비활성화 되어있습니다. 사이트 관리자에게 문의 해주세요.
disable_register_mail=죄송합니다. 메일 등록이 비활성화 되었습니다.
auth_source=Authentication Source
local=Local
local=로컬
remember_me=자동 로그인
forgot_password=비밀번호 찾기
forget_password=비밀번호를 잊으셨습니까?
@ -379,8 +379,8 @@ orgs.none=당신은 어떤 조직의 구성원도 아닙니다.
orgs.leave_title=조직 떠나기
orgs.leave_desc=조직을 떠난 후에는 모든 리포지토리와 팀에 액세스 할 수 없게 됩니다. 계속 하시겠습니까?
repos.leave=Leave
repos.leave_title=Leave repository
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!
@ -638,7 +638,7 @@ pulls.can_auto_merge_desc=이 풀리퀘스트는 자동적으로 머지될 수
pulls.cannot_auto_merge_desc=컨플릭이 존재해서 이 풀리퀘스트는 자동을 머지될 수 없습니다.
pulls.cannot_auto_merge_helper=컨플릭을 해결하려면 수동으로 머지해 주십시오.
pulls.create_merge_commit=Create a merge commit
pulls.rebase_before_merging=Rebase before merging
pulls.rebase_before_merging=병합 하기 전에 리베이스
pulls.merge_pull_request=풀리퀘스트 머지
pulls.open_unmerged_pull_exists=`같은 리파지토리에서 같은 머지 정보로 만들어진 풀리퀘스트 (#%d) 가 이미 오픈 상태이고 머지를 기다리고 있기 때문에 다시 열기 작업을 할 수 없습니다.`
pulls.delete_branch=브랜치 삭제
@ -1090,7 +1090,7 @@ repos.private=비공개
repos.watches=지켜보기
repos.stars=Stars
repos.issues=이슈
repos.size=Size
repos.size=크기
auths.auth_sources=Authentication Sources
auths.new=새로운 소스를 추가
@ -1112,10 +1112,10 @@ auths.user_base=사용자 검색 기준
auths.user_dn=사용자 DN
auths.attribute_username=유저 명 속성
auths.attribute_username_placeholder=사용자 이름에 대한 로그인 폼 필드 값을 사용하려면 비워 둡니다.
auths.attribute_name=First Name Attribute
auths.attribute_name=첫번째 이름 속성
auths.attribute_surname=성씨 속성
auths.attribute_mail=이메일 속성
auths.verify_group_membership=Verify group membership
auths.verify_group_membership=그룹 구성원 자격을 확인
auths.group_search_base_dn=Group Search Base DN
auths.group_filter=Group Filter
auths.group_attribute_contain_user_list=Group Attribute Containing List of Users

10
conf/locale/locale_pl-PL.ini

@ -151,8 +151,8 @@ register_hepler_msg=Masz już konto? Zaloguj się teraz!
social_register_hepler_msg=Masz już konto? Powiąż je teraz!
disable_register_prompt=Przepraszamy rejestracja została wyłączona. Prosimy o kontakt z administratorem serwisu.
disable_register_mail=Przepraszamy, potwierdzenia rejestracji zostały wyłączone przez administratora.
auth_source=Authentication Source
local=Local
auth_source=Źródło uwierzytelniania
local=Lokalne
remember_me=Zapamiętaj mnie
forgot_password=Zapomniałem hasła
forget_password=Zapomniałeś hasła?
@ -231,7 +231,7 @@ org_name_been_taken=Nazwa organizacji jest już zajęta.
team_name_been_taken=Nazwa zespołu jest już zajęta.
email_been_used=Adres e-mail jest już zarejestrowany.
username_password_incorrect=Nazwa użytkownika lub hasło nie jest prawidłowe.
auth_source_mismatch=The authentication source selected is not associated with the user.
auth_source_mismatch=Wybrane źródło uwierzytelniania nie jest związane z użytkownikiem.
enterred_invalid_repo_name=Upewnij się, że wprowadzona nazwa repozytorium jest poprawna.
enterred_invalid_owner_name=Upewnij się, że nazwa właściciela repozytorium jest poprawna.
enterred_invalid_password=Proszę upewnij się, że wprowadzono hasło jest poprawne.
@ -351,7 +351,7 @@ two_factor_or_enter_secret=Lub wprowadź sekret:
two_factor_then_enter_passcode=Następnie wprowadź kod dostępu:
two_factor_verify=Weryfikuj
two_factor_invalid_passcode=Wprowadzony kod nie jest prawidłowy, spróbuj ponownie!
two_factor_reused_passcode=The passcode you entered has already been used, please try another one!
two_factor_reused_passcode=Ten kod jest już używany, spróbuj ponownie!
two_factor_enable_error=Włączenie dwuetapowego uwierzytelniania nie powiodło się: %v
two_factor_enable_success=Uwierzytelnianie dwuetapowe Twojego konta zostało włączone pomyślnie!
two_factor_recovery_codes_title=Kody odzyskiwania uwierzytelniania dwuetapowego
@ -1091,7 +1091,7 @@ repos.stars=Polubienia
repos.issues=Problemy
repos.size=Rozmiar
auths.auth_sources=Authentication Sources
auths.auth_sources=Źródła uwierzytelniania
auths.new=Dodaj nowe źródło
auths.name=Nazwa
auths.type=Typ

2
conf/locale/locale_sr-SP.ini

@ -51,7 +51,7 @@ docker_helper=Ако покрећете Gogs унутар Docker, молимо
requite_db_desc=Gogs захтева MySQL, PostgreSQL, SQLite3, MSSQL или TiDB.
db_title=Подешавања базе
db_type=Тип базе података
host=Власник
host=Домаћин
user=Корисник
password=Лозинка
db_name=Назив базе података

2
conf/locale/locale_uk-UA.ini

@ -844,7 +844,7 @@ settings.slack_token=Токен
settings.slack_domain=Домен
settings.slack_channel=Канал
settings.deploy_keys=Ключи для розгортування
settings.deploy_keys_helper=<b>Common Gotcha!</b> Якщо ви шукаєте куди додати персональний публічний ключ, додайте його до <a href="%s%s">налаштуань вашого аккаунту</a>.
settings.deploy_keys_helper=<b>Common Gotcha!</b> Якщо ви шукаєте куди додати персональний публічний ключ, додайте його до <a href="%s%s">налаштувань вашого аккаунту</a>.
settings.add_deploy_key=Додати ключ для розгортування
settings.deploy_key_desc=Ключі розгортування доступні лише для читання. Це не те саме, що персональний SSH ключ акаунту.
settings.no_deploy_keys=Ви не додали жодного ключа для розгортування.

70
conf/locale/locale_zh-TW.ini

@ -1,7 +1,7 @@
app_desc=基於 Go 語言的自助 Git 服務
app_desc=一款極易搭建的自助 Git 服務
home=首頁
dashboard=控制面
dashboard=控制面
explore=探索
help=說明
sign_in=登入
@ -83,7 +83,7 @@ app_url_helper=該設置影響 HTTP/HTTPS 複製地址和一些郵箱中的連
log_root_path=日誌路徑
log_root_path_helper=寫入日誌檔目錄
enable_console_mode=開啟主控台模式
enable_console_mode_popup=In addition to file mode, also print logs to console.
enable_console_mode_popup=除了使用檔案模式之外, 還要將日誌列印到控制台。
optional_title=可選設置
email_title=電子郵件服務設定
@ -151,8 +151,8 @@ register_hepler_msg=已經註冊?立即登錄!
social_register_hepler_msg=已經註冊?立即綁定!
disable_register_prompt=對不起,註冊功能已被關閉。請聯系網站管理員。
disable_register_mail=對不起,註冊郵箱確認功能已被關閉。
auth_source=Authentication Source
local=Local
auth_source=認證來源
local=本地
remember_me=記住登錄
forgot_password=忘記密碼
forget_password=忘記密碼?
@ -231,7 +231,7 @@ org_name_been_taken=組織名稱已經被佔用。
team_name_been_taken=團隊名稱已經被佔用。
email_been_used=郵箱地址已經被使用。
username_password_incorrect=用戶名或密碼不正確。
auth_source_mismatch=The authentication source selected is not associated with the user.
auth_source_mismatch=此用戶未與所用的認證來源相關聯
enterred_invalid_repo_name=請檢查您輸入的倉庫名稱是正確。
enterred_invalid_owner_name=請檢查您輸入的新所有者用戶名是否正確。
enterred_invalid_password=請檢查您輸入的密碼是否正確。
@ -344,24 +344,24 @@ two_factor_off=關閉
two_factor_enable=啟用
two_factor_disable=禁用
two_factor_view_recovery_codes=在安全的地方查看並保存 <a href="%s%s"> 您的恢復代碼 </a>。如果您失去對身份驗證應用程式的存取權限, 則可以將它們用作密碼。
two_factor_http=For HTTP/HTTPS operations, you are no longer able to use plain username and password. Please create and use <a href="%[1]s%[2]s">Personal Access Token</a> as your credential, e.g. <code>%[3]s</code>.
two_factor_enable_title=Enable Two-factor Authentication
two_factor_http=對於HTTP/HTTPS操作,您不能使用用戶名稱和密碼作為憑據。請創建和使用<a href=“%[1]s%[2]s”>個人操作令牌</a>作為您的憑據,如<code>%[3]s</code>。
two_factor_enable_title=啟用兩步驗證
two_factor_scan_qr=請使用您的身份驗證應用程式掃描圖像:
two_factor_or_enter_secret=或輸入密碼: %s
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=啟用兩步驗證失敗: %v
two_factor_enable_success=您帳戶的兩步驗證已成功啟用!
two_factor_recovery_codes_title=兩步驗證恢復代碼
two_factor_recovery_codes_desc=Recovery codes are used when you temporarily lose access to your authentication application. Each recovery code can only be used once, <b>please keep these codes in a safe place</b>.
two_factor_recovery_codes_desc=當您無法存取您的認證應用程式時,可以使用救援代碼。每個救援代碼只能使用一次,因此 <b>請在安全的地方妥善保存您的救援代碼</b>。
two_factor_regenerate_recovery_codes=重新生成恢復代碼
two_factor_regenerate_recovery_codes_error=重新生成恢復代碼失敗: %v
two_factor_regenerate_recovery_codes_success=已成功生成新的恢復代碼!
two_factor_disable_title=Disable Two-factor Authentication
two_factor_disable_desc=Your account security level will decrease after disabled two-factor authentication. Do you want to continue?
two_factor_disable_success=Two-factor authentication has disabled successfully!
two_factor_disable_title=停用兩步驗證
two_factor_disable_desc=停用兩步驗證後,您的帳戶安全級別將降低。是否繼續?
two_factor_disable_success=您帳戶的兩步驗證已成功停用!
manage_access_token=管理個人操作令牌
generate_new_token=生成新的令牌
@ -382,7 +382,7 @@ orgs.leave_desc=離開組織後,所有與組織相關的倉庫和團隊權限
repos.leave=離開
repos.leave_title=離開存儲庫
repos.leave_desc=在你離開後,您將無法進入到存儲庫。你想要繼續嗎?
repos.leave_success=You have left repository '%s' successfully!
repos.leave_success=您已經成功退出「%s」版本庫!
delete_account=刪除當前帳戶
delete_prompt=刪除操作會永久清除您的帳戶信息,並且 <strong>不可恢復</strong>!
@ -454,7 +454,7 @@ quick_guide=快速幫助
clone_this_repo=複製當前倉庫
create_new_repo_command=從命令行創建一個新的倉庫
push_exist_repo=從命令行推送已經創建的倉庫
bare_message=This repository does not have any content yet.
bare_message=此版本庫空空如也。
files=檔案
branch=分支
@ -620,7 +620,7 @@ pulls.compare_compare=對比文件變化
pulls.filter_branch=過濾分支
pulls.no_results=未找到結果
pulls.nothing_to_compare=基準和對比分支代碼已經同步,無需進行對比。
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=請求將 %[1]d 次代碼提交從 <code>%[2]s</code> 合併至 <code>%[3]s</code>
@ -637,7 +637,7 @@ pulls.can_auto_merge_desc=這個拉請求可以自動合併。
pulls.cannot_auto_merge_desc=由於存在衝突,不能自動合併這推送請求。
pulls.cannot_auto_merge_helper=請手動合併來解決衝突。
pulls.create_merge_commit=創建一個合併提交
pulls.rebase_before_merging=Rebase before merging
pulls.rebase_before_merging=合併前先 Rebase
pulls.merge_pull_request=合併請求
pulls.open_unmerged_pull_exists=`由於已經存在來自相同倉庫和合併信息的未合併請求(#%d),您無法執行重新開啟操作。`
pulls.delete_branch=刪除分支
@ -693,11 +693,11 @@ 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=預設分支是程式碼 commit、pull requests 及線上編輯的基準分支。
settings.update=更新
settings.update_default_branch_unsupported=Change default branch is not supported by the Git version on server.
settings.update_default_branch_unsupported=伺服器的 Git 版本不支援變更預設分支。
settings.update_default_branch_success=這個 repository 的預設分支更新成功!
settings.protected_branches=保護分支
settings.protected_branches_desc=保護分支不被強制 Push、意外刪除以及限制 Commit 者白名單
@ -727,13 +727,13 @@ settings.change_reponame_prompt=該操作將會影響到所有與該倉庫有關
settings.advanced_settings=高級設置
settings.wiki_desc=啓用 Wiki 系統
settings.use_internal_wiki=使用內建 wiki
settings.allow_public_wiki_desc=Allow public access to wiki when repository is private
settings.allow_public_wiki_desc=當版本庫為私有狀態時,允許 Wiki 的公開存取。
settings.use_external_wiki=使用外部 wiki
settings.external_wiki_url=外部 Wiki 連結
settings.external_wiki_url_desc=當分頁上按一下,訪客將會重新導到 URL。
settings.issues_desc=啟用問題追蹤
settings.use_internal_issue_tracker=使用內建輕量級問題追蹤
settings.allow_public_issues_desc=Allow public access to issues when repository is private
settings.allow_public_issues_desc=當版本庫為私有狀態時,允許議題的公開存取。
settings.use_external_issue_tracker=使用外部的問題管理系統
settings.external_tracker_url=外部Issue Tracker網址
settings.external_tracker_url_desc=當訪客在分頁上按一下,他們將會重新導向到 URL。
@ -743,8 +743,8 @@ settings.tracker_issue_style.numeric=數字
settings.tracker_issue_style.alphanumeric=字母及數字
settings.tracker_url_format_desc=您可以使用 <code>{user} {repo} {index}</code> 分別作為用戶名、倉庫名和問題索引的占位符。
settings.pulls_desc=啟用合併請求以接受社區貢獻
settings.pulls.ignore_whitespace=Ignore changes in whitespace
settings.pulls.allow_rebase_merge=Allow use rebase to merge commits
settings.pulls.ignore_whitespace=忽略空白符號的更改
settings.pulls.allow_rebase_merge=允許使用 rebase 合併提交
settings.danger_zone=危險操作區
settings.cannot_fork_to_same_owner=你不可以 fork 一個 repository 到它的擁有者。
settings.new_owner_has_same_repo=新的倉庫擁有者已經存在同名倉庫!
@ -765,7 +765,7 @@ settings.wiki_deletion_success=儲存庫 wiki 資料已成功清除。
settings.delete=刪除本倉庫
settings.delete_desc=刪除倉庫操作不可逆轉,請三思而後行。
settings.delete_notices_1=- 此操作 <strong>不可以</strong> 被回滾。
settings.delete_notices_2=- This operation will permanently delete everything in this repository, including Git data, issues, comments and collaborator access.
settings.delete_notices_2=- 此動作將永久移除版本庫,包含了 Git 資料、議題、留言與協作者的存取權限。
settings.delete_notices_fork_1=- 刪除後所有的派生倉庫將會成為獨立倉庫
settings.deletion_success=倉庫刪除成功!
settings.update_settings_success=倉庫設置更新成功!
@ -790,7 +790,7 @@ settings.webhook.test_delivery=測試推送
settings.webhook.test_delivery_desc=生成並推送一個模擬的 Push 事件
settings.webhook.test_delivery_success=測試推送已經加入到隊列,請耐心等待數秒再刷新推送記錄。
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.redelivery_success=任務「%s」已經重新加入至隊列。可能需要幾秒鐘來更新歷史的隊列狀態
settings.webhook.request=請求內容
settings.webhook.response=響應內容
settings.webhook.headers=標題
@ -839,7 +839,7 @@ settings.recent_deliveries=最近推送記錄
settings.hook_type=鉤子類型
settings.add_slack_hook_desc=為您的倉庫增加 <a href="%s">Slack</a> 集成。
settings.add_discord_hook_desc=Hook <a href="%s">Discord</a> 到你的 repository。
settings.add_dingtalk_hook_desc=Add <a href="%s">Dingtalk</a> integration to your repository.
settings.add_dingtalk_hook_desc=在您的版本庫增加 <a href="%s">Dingtalk</a> 整合
settings.slack_token=令牌
settings.slack_domain=域名
settings.slack_channel=頻道
@ -1091,7 +1091,7 @@ repos.stars=讚好數
repos.issues=問題數
repos.size=大小
auths.auth_sources=Authentication Sources
auths.auth_sources=認證來源
auths.new=添加新認證源
auths.name=認證名稱
auths.type=認證類型
@ -1104,7 +1104,7 @@ auths.domain=域名
auths.host=主機地址
auths.port=主機端口
auths.bind_dn=綁定DN
auths.bind_dn_helper=You can use '%s' as placeholder for username, e.g. DOM\%s
auths.bind_dn_helper=可以使用'%s'作為用戶名稱的預留位置,例如:DOM\%s
auths.bind_password=綁定密碼
auths.bind_password_helper=警告:該密碼將會以明文的形式保存在數據庫中。請不要使用擁有高權限的帳戶!
auths.user_base=用戶搜索基準
@ -1115,9 +1115,9 @@ auths.attribute_name=歸納名字
auths.attribute_surname=姓氏屬性
auths.attribute_mail=電子郵箱屬性
auths.verify_group_membership=驗證組成員身份
auths.group_search_base_dn=Group Search Base DN
auths.group_search_base_dn=組蒐索基準 DN
auths.group_filter=組篩選器
auths.group_attribute_contain_user_list=Group Attribute Containing List of Users
auths.group_attribute_contain_user_list=包含使用者列表的群組屬性
auths.user_attribute_listed_in_group=組中列出的使用者屬性
auths.attributes_in_bind=從 Bind DN 中獲取屬性信息
auths.filter=使用者篩選器
@ -1166,7 +1166,7 @@ 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_rewrite_authorized_keys_at_start=在啟動時重寫 authorized_keys 檔案
config.ssh_key_test_path=金鑰測試路徑
config.ssh_keygen_path=金鑰產生 (' ssh-keygen ') 路徑
config.ssh_minimum_key_size_check=金鑰最小大小檢查
@ -1214,7 +1214,7 @@ config.skip_tls_verify=忽略 TLS 驗證
config.mailer_config=郵件配置
config.mailer_enabled=啟用服務
config.mailer_disable_helo=禁用 HELO 操作
config.mailer_subject_prefix=Subject Prefix
config.mailer_subject_prefix=主旨前置詞
config.mailer_host=郵件主機地址
config.mailer_user=發送者帳號
config.send_test_mail=發送測試郵件
@ -1304,9 +1304,9 @@ delete_branch=已經刪除在 <a href="%[1]s">%[3]s</a> 上的分支 <code>%[2]s
push_tag=推送了標籤 <a href="%s/src/%s">%[2]s</a> 到 <a href="%[1]s">%[3]s</a>
delete_tag=已經刪除在 <a href="%[1]s">%[3]s</a> 上的標籤 <code>%[2]s</code>
fork_repo=已經 fork 一個 repository 到 <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
mirror_sync_delete=synced and deleted reference <code>%[2]s</code> at <a href="%[1]s">%[3]s</a> from mirror
mirror_sync_push=已經從鏡像同步了提交 <a href="%[1]s/src/%[2]s">%[3]s</a> 於 <a href="%[1]s">%[4]s</a>
mirror_sync_create=已經從鏡像同步了參考 <a href="%s/src/%s">%[2]s</a> 到 <a href="%[1]s">%[3]s</a>
mirror_sync_delete=已經從鏡像同步並移除了參考 <code>%[2]s</code> 於 <a href="%[1]s">%[3]s</a>
[tool]
ago=之前

10
docker/build.sh

@ -23,7 +23,9 @@ rm -r $GOPATH
# Remove build deps
apk --no-progress del build-deps
# Create git user for Gogs
addgroup -S git
adduser -G git -H -D -g 'Gogs Git User' git -h /data/git -s /bin/bash && usermod -p '*' git && passwd -u git
echo "export GOGS_CUSTOM=${GOGS_CUSTOM}" >> /etc/profile
# Move to final place
mv /app/gogs/build/gogs /app/gogs/
# Cleanup go
rm -rf /tmp/go
rm -rf /usr/local/go

9
docker/finalize.sh

@ -4,8 +4,10 @@
set -x
set -e
# Move to final place
mv /app/gogs/build/gogs /app/gogs/
# Create git user for Gogs
addgroup -S git
adduser -G git -H -D -g 'Gogs Git User' git -h /data/git -s /bin/bash && usermod -p '*' git && passwd -u git
echo "export GOGS_CUSTOM=${GOGS_CUSTOM}" >> /etc/profile
# Final cleaning
rm -rf /app/gogs/build
@ -14,6 +16,3 @@ rm /app/gogs/docker/build-go.sh
rm /app/gogs/docker/finalize.sh
rm /app/gogs/docker/nsswitch.conf
rm /app/gogs/docker/README.md
rm -rf /tmp/go
rm -rf /usr/local/go

3
gogs.go

@ -16,7 +16,7 @@ import (
"github.com/gogs/gogs/pkg/setting"
)
const APP_VER = "0.11.58.0618"
const APP_VER = "0.11.63.0817"
func init() {
setting.AppVer = APP_VER
@ -37,6 +37,5 @@ func main() {
cmd.Backup,
cmd.Restore,
}
app.Flags = append(app.Flags, []cli.Flag{}...)
app.Run(os.Args)
}

2
models/attachment.go

@ -165,7 +165,6 @@ func DeleteAttachments(attachments []*Attachment, remove bool) (int, error) {
// DeleteAttachmentsByIssue deletes all attachments associated with the given issue.
func DeleteAttachmentsByIssue(issueId int64, remove bool) (int, error) {
attachments, err := GetAttachmentsByIssueID(issueId)
if err != nil {
return 0, err
}
@ -176,7 +175,6 @@ func DeleteAttachmentsByIssue(issueId int64, remove bool) (int, error) {
// DeleteAttachmentsByComment deletes all attachments associated with the given comment.
func DeleteAttachmentsByComment(commentId int64, remove bool) (int, error) {
attachments, err := GetAttachmentsByCommentID(commentId)
if err != nil {
return 0, err
}

17
models/comment.go

@ -132,14 +132,6 @@ func (c *Comment) LoadAttributes() error {
return c.loadAttributes(x)
}
func (c *Comment) AfterDelete() {
_, err := DeleteAttachmentsByComment(c.ID, true)
if err != nil {
log.Info("Could not delete files for comment %d on issue #%d: %s", c.ID, c.IssueID, err)
}
}
func (c *Comment) HTMLURL() string {
return fmt.Sprintf("%s#issuecomment-%d", c.Issue.HTMLURL(), c.ID)
}
@ -508,7 +500,7 @@ func DeleteCommentByID(doer *User, id int64) error {
return err
}
if _, err = sess.Id(comment.ID).Delete(new(Comment)); err != nil {
if _, err = sess.ID(comment.ID).Delete(new(Comment)); err != nil {
return err
}
@ -519,7 +511,12 @@ func DeleteCommentByID(doer *User, id int64) error {
}
if err = sess.Commit(); err != nil {
return fmt.Errorf("Commit: %v", err)
return fmt.Errorf("commit: %v", err)
}
_, err = DeleteAttachmentsByComment(comment.ID, true)
if err != nil {
log.Error(2, "Failed to delete attachments by comment[%d]: %v", comment.ID, err)
}
if err = comment.Issue.LoadAttributes(); err != nil {

2
models/errors/errors.go

@ -6,6 +6,8 @@ package errors
import "errors"
var InternalServerError = errors.New("internal server error")
// New is a wrapper of real errors.New function.
func New(text string) error {
return errors.New(text)

8
models/issue.go

@ -402,7 +402,7 @@ func (i *Issue) ReadBy(uid int64) error {
}
func updateIssueCols(e Engine, issue *Issue, cols ...string) error {
_, err := e.Id(issue.ID).Cols(cols...).Update(issue)
_, err := e.ID(issue.ID).Cols(cols...).Update(issue)
return err
}
@ -843,7 +843,7 @@ func GetIssueByIndex(repoID, index int64) (*Issue, error) {
func getRawIssueByID(e Engine, id int64) (*Issue, error) {
issue := new(Issue)
has, err := e.Id(id).Get(issue)
has, err := e.ID(id).Get(issue)
if err != nil {
return nil, err
} else if !has {
@ -1354,7 +1354,7 @@ func GetRepoIssueStats(repoID, userID int64, filterMode FilterMode, isPull bool)
}
func updateIssue(e Engine, issue *Issue) error {
_, err := e.Id(issue.ID).AllCols().Update(issue)
_, err := e.ID(issue.ID).AllCols().Update(issue)
return err
}
@ -1423,7 +1423,7 @@ func updateIssueUsersByMentions(e Engine, issueID int64, uids []int64) error {
iu.IsMentioned = true
if has {
_, err = e.Id(iu.ID).AllCols().Update(iu)
_, err = e.ID(iu.ID).AllCols().Update(iu)
} else {
_, err = e.Insert(iu)
}

4
models/issue_label.go

@ -196,7 +196,7 @@ func GetLabelsByIssueID(issueID int64) ([]*Label, error) {
}
func updateLabel(e Engine, l *Label) error {
_, err := e.Id(l.ID).AllCols().Update(l)
_, err := e.ID(l.ID).AllCols().Update(l)
return err
}
@ -221,7 +221,7 @@ func DeleteLabel(repoID, labelID int64) error {
return err
}
if _, err = sess.Id(labelID).Delete(new(Label)); err != nil {
if _, err = sess.ID(labelID).Delete(new(Label)); err != nil {
return err
} else if _, err = sess.Where("label_id = ?", labelID).Delete(new(IssueLabel)); err != nil {
return err

2
models/migrations/migrations.go

@ -162,7 +162,7 @@ func generateOrgRandsAndSalt(x *xorm.Engine) (err error) {
if org.Salt, err = tool.RandomString(10); err != nil {
return err
}
if _, err = sess.Id(org.ID).Update(org); err != nil {
if _, err = sess.ID(org.ID).Update(org); err != nil {
return err
}
}

8
models/milestone.go

@ -166,7 +166,7 @@ func GetMilestones(repoID int64, page int, isClosed bool) ([]*Milestone, error)
}
func updateMilestone(e Engine, m *Milestone) error {
_, err := e.Id(m.ID).AllCols().Update(m)
_, err := e.ID(m.ID).AllCols().Update(m)
return err
}
@ -223,7 +223,7 @@ func ChangeMilestoneStatus(m *Milestone, isClosed bool) (err error) {
repo.NumMilestones = int(countRepoMilestones(sess, repo.ID))
repo.NumClosedMilestones = int(countRepoClosedMilestones(sess, repo.ID))
if _, err = sess.Id(repo.ID).AllCols().Update(repo); err != nil {
if _, err = sess.ID(repo.ID).AllCols().Update(repo); err != nil {
return err
}
return sess.Commit()
@ -383,13 +383,13 @@ func DeleteMilestoneOfRepoByID(repoID, id int64) error {
return err
}
if _, err = sess.Id(m.ID).Delete(new(Milestone)); err != nil {
if _, err = sess.ID(m.ID).Delete(new(Milestone)); err != nil {
return err
}
repo.NumMilestones = int(countRepoMilestones(sess, repo.ID))
repo.NumClosedMilestones = int(countRepoClosedMilestones(sess, repo.ID))
if _, err = sess.Id(repo.ID).AllCols().Update(repo); err != nil {
if _, err = sess.ID(repo.ID).AllCols().Update(repo); err != nil {
return err
}

2
models/mirror.go

@ -320,7 +320,7 @@ func GetMirrorByRepoID(repoID int64) (*Mirror, error) {
}
func updateMirror(e Engine, m *Mirror) error {
_, err := e.Id(m.ID).AllCols().Update(m)
_, err := e.ID(m.ID).AllCols().Update(m)
return err
}

21
models/models.go

@ -33,7 +33,7 @@ type Engine interface {
Exec(string, ...interface{}) (sql.Result, error)
Find(interface{}, ...interface{}) error
Get(interface{}) (bool, error)
Id(interface{}) *xorm.Session
ID(interface{}) *xorm.Session
In(string, ...interface{}) *xorm.Session
Insert(...interface{}) (int64, error)
InsertOne(interface{}) (int64, error)
@ -300,7 +300,8 @@ func ImportDatabase(dirPath string, verbose bool) (err error) {
snakeMapper := core.SnakeMapper{}
skipInsertProcessors := map[string]bool{
"mirror": true,
"mirror": true,
"milestone": true,
}
// Purposely create a local variable to not modify global variable
@ -359,16 +360,24 @@ func ImportDatabase(dirPath string, verbose bool) (err error) {
return fmt.Errorf("insert strcut: %v", err)
}
meta := make(map[string]interface{})
if err = jsoniter.Unmarshal(scanner.Bytes(), &meta); err != nil {
log.Error(2, "Failed to unmarshal to map: %v", err)
}
// Reset created_unix back to the date save in archive because Insert method updates its value
if isInsertProcessor && !skipInsertProcessors[rawTableName] {
meta := make(map[string]interface{})
if err = jsoniter.Unmarshal(scanner.Bytes(), &meta); err != nil {
log.Error(2, "Failed to unmarshal to map: %v", err)
}
if _, err = x.Exec("UPDATE "+rawTableName+" SET created_unix=? WHERE id=?", meta["CreatedUnix"], meta["ID"]); err != nil {
log.Error(2, "Failed to reset 'created_unix': %v", err)
}
}
switch rawTableName {
case "milestone":
if _, err = x.Exec("UPDATE "+rawTableName+" SET deadline_unix=?, closed_date_unix=? WHERE id=?", meta["DeadlineUnix"], meta["ClosedDateUnix"], meta["ID"]); err != nil {
log.Error(2, "Failed to reset 'milestone.deadline_unix', 'milestone.closed_date_unix': %v", err)
}
}
}
// PostgreSQL needs manually reset table sequence for auto increment keys

2
models/org.go

@ -410,7 +410,7 @@ func RemoveOrgUser(orgID, userID int64) error {
return err
}
if _, err := sess.Id(ou.ID).Delete(ou); err != nil {
if _, err := sess.ID(ou.ID).Delete(ou); err != nil {
return err
} else if _, err = sess.Exec("UPDATE `user` SET num_members=num_members-1 WHERE id=?", orgID); err != nil {
return err

20
models/org_team.go

@ -111,7 +111,7 @@ func (t *Team) addRepository(e Engine, repo *Repository) (err error) {
}
t.NumRepos++
if _, err = e.Id(t.ID).AllCols().Update(t); err != nil {
if _, err = e.ID(t.ID).AllCols().Update(t); err != nil {
return fmt.Errorf("update team: %v", err)
}
@ -157,7 +157,7 @@ func (t *Team) removeRepository(e Engine, repo *Repository, recalculate bool) (e
}
t.NumRepos--
if _, err = e.Id(t.ID).AllCols().Update(t); err != nil {
if _, err = e.ID(t.ID).AllCols().Update(t); err != nil {
return err
}
@ -286,7 +286,7 @@ func GetTeamOfOrgByName(orgID int64, name string) (*Team, error) {
func getTeamByID(e Engine, teamID int64) (*Team, error) {
t := new(Team)
has, err := e.Id(teamID).Get(t)
has, err := e.ID(teamID).Get(t)
if err != nil {
return nil, err
} else if !has {
@ -334,7 +334,7 @@ func UpdateTeam(t *Team, authChanged bool) (err error) {
return ErrTeamAlreadyExist{t.OrgID, t.LowerName}
}
if _, err = sess.Id(t.ID).AllCols().Update(t); err != nil {
if _, err = sess.ID(t.ID).AllCols().Update(t); err != nil {
return fmt.Errorf("update: %v", err)
}
@ -386,7 +386,7 @@ func DeleteTeam(t *Team) error {
}
// Delete team.
if _, err = sess.Id(t.ID).Delete(new(Team)); err != nil {
if _, err = sess.ID(t.ID).Delete(new(Team)); err != nil {
return err
}
// Update organization number of teams.
@ -431,7 +431,7 @@ func getTeamMembers(e Engine, teamID int64) (_ []*User, err error) {
members := make([]*User, 0, len(teamUsers))
for i := range teamUsers {
member := new(User)
if _, err = e.Id(teamUsers[i].UID).Get(member); err != nil {
if _, err = e.ID(teamUsers[i].UID).Get(member); err != nil {
return nil, fmt.Errorf("get user '%d': %v", teamUsers[i].UID, err)
}
members = append(members, member)
@ -500,7 +500,7 @@ func AddTeamMember(orgID, teamID, userID int64) error {
}
if _, err = sess.Insert(tu); err != nil {
return err
} else if _, err = sess.Id(t.ID).Update(t); err != nil {
} else if _, err = sess.ID(t.ID).Update(t); err != nil {
return err
}
@ -520,7 +520,7 @@ func AddTeamMember(orgID, teamID, userID int64) error {
if t.IsOwnerTeam() {
ou.IsOwner = true
}
if _, err = sess.Id(ou.ID).AllCols().Update(ou); err != nil {
if _, err = sess.ID(ou.ID).AllCols().Update(ou); err != nil {
return err
}
@ -562,7 +562,7 @@ func removeTeamMember(e Engine, orgID, teamID, uid int64) error {
}
if _, err := e.Delete(tu); err != nil {
return err
} else if _, err = e.Id(t.ID).AllCols().Update(t); err != nil {
} else if _, err = e.ID(t.ID).AllCols().Update(t); err != nil {
return err
}
@ -583,7 +583,7 @@ func removeTeamMember(e Engine, orgID, teamID, uid int64) error {
if t.IsOwnerTeam() {
ou.IsOwner = false
}
if _, err = e.Id(ou.ID).AllCols().Update(ou); err != nil {
if _, err = e.ID(ou.ID).AllCols().Update(ou); err != nil {
return err
}
return nil

9
models/pull.go

@ -193,7 +193,7 @@ const (
// Merge merges pull request to base repository.
// FIXME: add repoWorkingPull make sure two merges does not happen at same time.
func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle MergeStyle) (err error) {
func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle MergeStyle, commitDescription string) (err error) {
defer func() {
go HookQueue.Add(pr.BaseRepo.ID)
go AddTestPullRequestTask(doer, pr.BaseRepo.ID, pr.BaseBranch, false)
@ -266,7 +266,8 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
if _, stderr, err = process.ExecDir(-1, tmpBasePath,
fmt.Sprintf("PullRequest.Merge (git merge): %s", tmpBasePath),
"git", "commit", fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email),
"-m", fmt.Sprintf("Merge branch '%s' of %s/%s into %s", pr.HeadBranch, pr.HeadUserName, pr.HeadRepo.Name, pr.BaseBranch)); err != nil {
"-m", fmt.Sprintf("Merge branch '%s' of %s/%s into %s", pr.HeadBranch, pr.HeadUserName, pr.HeadRepo.Name, pr.BaseBranch),
"-m", commitDescription); err != nil {
return fmt.Errorf("git commit [%s]: %v - %s", tmpBasePath, err, stderr)
}
@ -320,7 +321,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
pr.HasMerged = true
pr.Merged = time.Now()
pr.MergerID = doer.ID
if _, err = sess.Id(pr.ID).AllCols().Update(pr); err != nil {
if _, err = sess.ID(pr.ID).AllCols().Update(pr); err != nil {
return fmt.Errorf("update pull request: %v", err)
}
@ -545,7 +546,7 @@ func GetUnmergedPullRequestsByBaseInfo(repoID int64, branch string) ([]*PullRequ
func getPullRequestByID(e Engine, id int64) (*PullRequest, error) {
pr := new(PullRequest)
has, err := e.Id(id).Get(pr)
has, err := e.ID(id).Get(pr)
if err != nil {
return nil, err
} else if !has {

2
models/release.go

@ -293,7 +293,7 @@ func UpdateRelease(doer *User, gitRepo *git.Repository, r *Release, isPublish bo
if err = sess.Begin(); err != nil {
return err
}
if _, err = sess.Id(r.ID).AllCols().Update(r); err != nil {
if _, err = sess.ID(r.ID).AllCols().Update(r); err != nil {
return fmt.Errorf("Update: %v", err)
}

12
models/repo.go

@ -1264,7 +1264,7 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
repo.Owner = newOwner
// Update repository.
if _, err := sess.Id(repo.ID).Update(repo); err != nil {
if _, err := sess.ID(repo.ID).Update(repo); err != nil {
return fmt.Errorf("update owner: %v", err)
}
@ -1296,7 +1296,7 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
}
t.NumRepos--
if _, err := sess.Id(t.ID).AllCols().Update(t); err != nil {
if _, err := sess.ID(t.ID).AllCols().Update(t); err != nil {
return fmt.Errorf("decrease team repository count '%d': %v", t.ID, err)
}
}
@ -1409,7 +1409,7 @@ func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err e
repo.Website = repo.Website[:255]
}
if _, err = e.Id(repo.ID).AllCols().Update(repo); err != nil {
if _, err = e.ID(repo.ID).AllCols().Update(repo); err != nil {
return fmt.Errorf("update: %v", err)
}
@ -1625,7 +1625,7 @@ func GetRepositoryByName(ownerID int64, name string) (*Repository, error) {
func getRepositoryByID(e Engine, id int64) (*Repository, error) {
repo := new(Repository)
has, err := e.Id(id).Get(repo)
has, err := e.ID(id).Get(repo)
if err != nil {
return nil, err
} else if !has {
@ -2348,6 +2348,10 @@ 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()}
}
repo := &Repository{
OwnerID: owner.ID,
Owner: owner,

4
models/repo_branch.go

@ -131,7 +131,7 @@ func UpdateProtectBranch(protectBranch *ProtectBranch) (err error) {
}
}
if _, err = sess.Id(protectBranch.ID).AllCols().Update(protectBranch); err != nil {
if _, err = sess.ID(protectBranch.ID).AllCols().Update(protectBranch); err != nil {
return fmt.Errorf("Update: %v", err)
}
@ -234,7 +234,7 @@ func UpdateOrgProtectBranch(repo *Repository, protectBranch *ProtectBranch, whit
return err
}
if _, err = sess.Id(protectBranch.ID).AllCols().Update(protectBranch); err != nil {
if _, err = sess.ID(protectBranch.ID).AllCols().Update(protectBranch); err != nil {
return fmt.Errorf("Update: %v", err)
}

2
models/repo_collaboration.go

@ -170,7 +170,7 @@ func (repo *Repository) ChangeCollaborationAccessMode(userID int64, mode AccessM
return err
}
if _, err = sess.Id(collaboration.ID).AllCols().Update(collaboration); err != nil {
if _, err = sess.ID(collaboration.ID).AllCols().Update(collaboration); err != nil {
return fmt.Errorf("update collaboration: %v", err)
}

229
models/repo_editor.go

@ -17,15 +17,50 @@ import (
"github.com/Unknwon/com"
gouuid "github.com/satori/go.uuid"
log "gopkg.in/clog.v1"
git "github.com/gogs/git-module"
"github.com/gogs/git-module"
"github.com/gogs/gogs/models/errors"
"github.com/gogs/gogs/pkg/process"
"github.com/gogs/gogs/pkg/setting"
"github.com/gogs/gogs/pkg/tool"
)
const (
ENV_AUTH_USER_ID = "GOGS_AUTH_USER_ID"
ENV_AUTH_USER_NAME = "GOGS_AUTH_USER_NAME"
ENV_AUTH_USER_EMAIL = "GOGS_AUTH_USER_EMAIL"
ENV_REPO_OWNER_NAME = "GOGS_REPO_OWNER_NAME"
ENV_REPO_OWNER_SALT_MD5 = "GOGS_REPO_OWNER_SALT_MD5"
ENV_REPO_ID = "GOGS_REPO_ID"
ENV_REPO_NAME = "GOGS_REPO_NAME"
ENV_REPO_CUSTOM_HOOKS_PATH = "GOGS_REPO_CUSTOM_HOOKS_PATH"
)
type ComposeHookEnvsOptions struct {
AuthUser *User
OwnerName string
OwnerSalt string
RepoID int64
RepoName string
RepoPath string
}
func ComposeHookEnvs(opts ComposeHookEnvsOptions) []string {
envs := []string{
"SSH_ORIGINAL_COMMAND=1",
ENV_AUTH_USER_ID + "=" + com.ToStr(opts.AuthUser.ID),
ENV_AUTH_USER_NAME + "=" + opts.AuthUser.Name,
ENV_AUTH_USER_EMAIL + "=" + opts.AuthUser.Email,
ENV_REPO_OWNER_NAME + "=" + opts.OwnerName,
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"),
}
return envs
}
// ___________ .___.__ __ ___________.__.__
// \_ _____/ __| _/|__|/ |_ \_ _____/|__| | ____
// | __)_ / __ | | \ __\ | __) | | | _/ __ \
@ -88,9 +123,9 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
if err = repo.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil {
return fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", opts.OldBranch, err)
return fmt.Errorf("discard local repo branch[%s] changes: %v", opts.OldBranch, err)
} else if err = repo.UpdateLocalCopyBranch(opts.OldBranch); err != nil {
return fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", opts.OldBranch, err)
return fmt.Errorf("update local copy branch[%s]: %v", opts.OldBranch, err)
}
repoPath := repo.RepoPath()
@ -107,12 +142,12 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
if err = git.DeleteBranch(localPath, opts.NewBranch, git.DeleteBranchOptions{
Force: true,
}); err != nil {
return fmt.Errorf("DeleteBranch [name: %s]: %v", opts.NewBranch, err)
return fmt.Errorf("delete branch[%s]: %v", opts.NewBranch, err)
}
}
if err := repo.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil {
return fmt.Errorf("CheckoutNewBranch [old_branch: %s, new_branch: %s]: %v", opts.OldBranch, opts.NewBranch, err)
return fmt.Errorf("checkout new branch[%s] from old branch[%s]: %v", opts.NewBranch, opts.OldBranch, err)
}
}
@ -131,12 +166,12 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
// Otherwise, move the file when name changed.
if com.IsFile(oldFilePath) && opts.OldTreeName != opts.NewTreeName {
if err = git.MoveFile(localPath, opts.OldTreeName, opts.NewTreeName); err != nil {
return fmt.Errorf("git mv %s %s: %v", opts.OldTreeName, opts.NewTreeName, err)
return fmt.Errorf("git mv %q %q: %v", opts.OldTreeName, opts.NewTreeName, err)
}
}
if err = ioutil.WriteFile(filePath, []byte(opts.Content), 0666); err != nil {
return fmt.Errorf("WriteFile: %v", err)
return fmt.Errorf("write file: %v", err)
}
if err = git.AddChanges(localPath, true); err != nil {
@ -145,45 +180,18 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
Committer: doer.NewGitSig(),
Message: opts.Message,
}); err != nil {
return fmt.Errorf("CommitChanges: %v", err)
} else if err = git.Push(localPath, "origin", opts.NewBranch); 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 {
return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err)
}
gitRepo, err := git.OpenRepository(repo.RepoPath())
if err != nil {
log.Error(2, "OpenRepository: %v", err)
return nil
}
commit, err := gitRepo.GetBranchCommit(opts.NewBranch)
if err != nil {
log.Error(2, "GetBranchCommit [branch: %s]: %v", opts.NewBranch, err)
return nil
}
// Simulate push event.
pushCommits := &PushCommits{
Len: 1,
Commits: []*PushCommit{CommitToPushCommit(commit)},
}
oldCommitID := opts.LastCommitID
if opts.NewBranch != opts.OldBranch {
oldCommitID = git.EMPTY_SHA
}
if err := CommitRepoAction(CommitRepoActionOptions{
PusherName: doer.Name,
RepoOwnerID: repo.MustOwner().ID,
RepoName: repo.Name,
RefFullName: git.BRANCH_PREFIX + opts.NewBranch,
OldCommitID: oldCommitID,
NewCommitID: commit.ID.String(),
Commits: pushCommits,
}); err != nil {
log.Error(2, "CommitRepoAction: %v", err)
return nil
}
go AddTestPullRequestTask(doer, repo.ID, opts.NewBranch, true)
return nil
}
@ -193,16 +201,16 @@ func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
if err = repo.DiscardLocalRepoBranchChanges(branch); err != nil {
return nil, fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", branch, err)
return nil, fmt.Errorf("discard local repo branch[%s] changes: %v", branch, err)
} else if err = repo.UpdateLocalCopyBranch(branch); err != nil {
return nil, fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", branch, err)
return nil, fmt.Errorf("update local copy branch[%s]: %v", branch, err)
}
localPath := repo.LocalCopyPath()
filePath := path.Join(localPath, treePath)
os.MkdirAll(filepath.Dir(filePath), os.ModePerm)
if err = ioutil.WriteFile(filePath, []byte(content), 0666); err != nil {
return nil, fmt.Errorf("WriteFile: %v", err)
return nil, fmt.Errorf("write file: %v", err)
}
cmd := exec.Command("git", "diff", treePath)
@ -211,11 +219,11 @@ func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, fmt.Errorf("StdoutPipe: %v", err)
return nil, fmt.Errorf("get stdout pipe: %v", err)
}
if err = cmd.Start(); err != nil {
return nil, fmt.Errorf("Start: %v", err)
return nil, fmt.Errorf("start: %v", err)
}
pid := process.Add(fmt.Sprintf("GetDiffPreview [repo_path: %s]", repo.RepoPath()), cmd)
@ -223,11 +231,11 @@ func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *
diff, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, stdout)
if err != nil {
return nil, fmt.Errorf("ParsePatch: %v", err)
return nil, fmt.Errorf("parse path: %v", err)
}
if err = cmd.Wait(); err != nil {
return nil, fmt.Errorf("Wait: %v", err)
return nil, fmt.Errorf("wait: %v", err)
}
return diff, nil
@ -254,20 +262,20 @@ func (repo *Repository) DeleteRepoFile(doer *User, opts DeleteRepoFileOptions) (
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
if err = repo.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil {
return fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", opts.OldBranch, err)
return fmt.Errorf("discard local repo branch[%s] changes: %v", opts.OldBranch, err)
} else if err = repo.UpdateLocalCopyBranch(opts.OldBranch); err != nil {
return fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", opts.OldBranch, err)
return fmt.Errorf("update local copy branch[%s]: %v", opts.OldBranch, err)
}
if opts.OldBranch != opts.NewBranch {
if err := repo.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil {
return fmt.Errorf("CheckoutNewBranch [old_branch: %s, new_branch: %s]: %v", opts.OldBranch, opts.NewBranch, err)
return fmt.Errorf("checkout new branch[%s] from old branch[%s]: %v", opts.NewBranch, opts.OldBranch, err)
}
}
localPath := repo.LocalCopyPath()
if err = os.Remove(path.Join(localPath, opts.TreePath)); err != nil {
return fmt.Errorf("Remove: %v", err)
return fmt.Errorf("remove file %q: %v", opts.TreePath, err)
}
if err = git.AddChanges(localPath, true); err != nil {
@ -276,41 +284,18 @@ func (repo *Repository) DeleteRepoFile(doer *User, opts DeleteRepoFileOptions) (
Committer: doer.NewGitSig(),
Message: opts.Message,
}); err != nil {
return fmt.Errorf("CommitChanges: %v", err)
} else if err = git.Push(localPath, "origin", opts.NewBranch); 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 {
return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err)
}
gitRepo, err := git.OpenRepository(repo.RepoPath())
if err != nil {
log.Error(2, "OpenRepository: %v", err)
return nil
}
commit, err := gitRepo.GetBranchCommit(opts.NewBranch)
if err != nil {
log.Error(2, "GetBranchCommit [branch: %s]: %v", opts.NewBranch, err)
return nil
}
// Simulate push event.
pushCommits := &PushCommits{
Len: 1,
Commits: []*PushCommit{CommitToPushCommit(commit)},
}
if err := CommitRepoAction(CommitRepoActionOptions{
PusherName: doer.Name,
RepoOwnerID: repo.MustOwner().ID,
RepoName: repo.Name,
RefFullName: git.BRANCH_PREFIX + opts.NewBranch,
OldCommitID: opts.LastCommitID,
NewCommitID: commit.ID.String(),
Commits: pushCommits,
}); err != nil {
log.Error(2, "CommitRepoAction: %v", err)
return nil
}
go AddTestPullRequestTask(doer, repo.ID, opts.NewBranch, true)
return nil
}
@ -348,19 +333,19 @@ func NewUpload(name string, buf []byte, file multipart.File) (_ *Upload, err err
localPath := upload.LocalPath()
if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil {
return nil, fmt.Errorf("MkdirAll: %v", err)
return nil, fmt.Errorf("mkdir all: %v", err)
}
fw, err := os.Create(localPath)
if err != nil {
return nil, fmt.Errorf("Create: %v", err)
return nil, fmt.Errorf("create: %v", err)
}
defer fw.Close()
if _, err = fw.Write(buf); err != nil {
return nil, fmt.Errorf("Write: %v", err)
return nil, fmt.Errorf("write: %v", err)
} else if _, err = io.Copy(fw, file); err != nil {
return nil, fmt.Errorf("Copy: %v", err)
return nil, fmt.Errorf("copy: %v", err)
}
if _, err := x.Insert(upload); err != nil {
@ -434,11 +419,11 @@ func DeleteUploadByUUID(uuid string) error {
if IsErrUploadNotExist(err) {
return nil
}
return fmt.Errorf("GetUploadByUUID: %v", err)
return fmt.Errorf("get upload by UUID[%s]: %v", uuid, err)
}
if err := DeleteUpload(upload); err != nil {
return fmt.Errorf("DeleteUpload: %v", err)
return fmt.Errorf("delete upload: %v", err)
}
return nil
@ -450,7 +435,7 @@ type UploadRepoFileOptions struct {
NewBranch string
TreePath string
Message string
Files []string // In UUID format.
Files []string // In UUID format
}
func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions) (err error) {
@ -460,21 +445,21 @@ func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions)
uploads, err := GetUploadsByUUIDs(opts.Files)
if err != nil {
return fmt.Errorf("GetUploadsByUUIDs [uuids: %v]: %v", opts.Files, err)
return fmt.Errorf("get uploads by UUIDs[%v]: %v", opts.Files, err)
}
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
if err = repo.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil {
return fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", opts.OldBranch, err)
return fmt.Errorf("discard local repo branch[%s] changes: %v", opts.OldBranch, err)
} else if err = repo.UpdateLocalCopyBranch(opts.OldBranch); err != nil {
return fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", opts.OldBranch, err)
return fmt.Errorf("update local copy branch[%s]: %v", opts.OldBranch, err)
}
if opts.OldBranch != opts.NewBranch {
if err = repo.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil {
return fmt.Errorf("CheckoutNewBranch [old_branch: %s, new_branch: %s]: %v", opts.OldBranch, opts.NewBranch, err)
return fmt.Errorf("checkout new branch[%s] from old branch[%s]: %v", opts.NewBranch, opts.OldBranch, err)
}
}
@ -491,7 +476,7 @@ func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions)
}
if err = com.Copy(tmpPath, targetPath); err != nil {
return fmt.Errorf("Copy: %v", err)
return fmt.Errorf("copy: %v", err)
}
}
@ -501,40 +486,18 @@ func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions)
Committer: doer.NewGitSig(),
Message: opts.Message,
}); err != nil {
return fmt.Errorf("CommitChanges: %v", err)
} else if err = git.Push(localPath, "origin", opts.NewBranch); 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 {
return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err)
}
gitRepo, err := git.OpenRepository(repo.RepoPath())
if err != nil {
log.Error(2, "OpenRepository: %v", err)
return nil
}
commit, err := gitRepo.GetBranchCommit(opts.NewBranch)
if err != nil {
log.Error(2, "GetBranchCommit [branch: %s]: %v", opts.NewBranch, err)
return nil
}
// Simulate push event.
pushCommits := &PushCommits{
Len: 1,
Commits: []*PushCommit{CommitToPushCommit(commit)},
}
if err := CommitRepoAction(CommitRepoActionOptions{
PusherName: doer.Name,
RepoOwnerID: repo.MustOwner().ID,
RepoName: repo.Name,
RefFullName: git.BRANCH_PREFIX + opts.NewBranch,
OldCommitID: opts.LastCommitID,
NewCommitID: commit.ID.String(),
Commits: pushCommits,
}); err != nil {
log.Error(2, "CommitRepoAction: %v", err)
return nil
}
go AddTestPullRequestTask(doer, repo.ID, opts.NewBranch, true)
return DeleteUploads(uploads...)
}

5
models/ssh_key.go

@ -25,7 +25,6 @@ import (
"github.com/gogs/gogs/pkg/process"
"github.com/gogs/gogs/pkg/setting"
"github.com/gogs/gogs/pkg/tool"
)
const (
@ -479,7 +478,7 @@ func deletePublicKeys(e *xorm.Session, keyIDs ...int64) error {
return nil
}
_, err := e.In("id", strings.Join(tool.Int64sToStrings(keyIDs), ",")).Delete(new(PublicKey))
_, err := e.In("id", keyIDs).Delete(new(PublicKey))
return err
}
@ -748,7 +747,7 @@ func DeleteDeployKey(doer *User, id int64) error {
return err
}
if _, err = sess.Id(key.ID).Delete(new(DeployKey)); err != nil {
if _, err = sess.ID(key.ID).Delete(new(DeployKey)); err != nil {
return fmt.Errorf("delete deploy key [%d]: %v", key.ID, err)
}

4
models/user.go

@ -706,7 +706,7 @@ func updateUser(e Engine, u *User) error {
u.Website = tool.TruncateString(u.Website, 255)
u.Description = tool.TruncateString(u.Description, 255)
_, err := e.Id(u.ID).AllCols().Update(u)
_, err := e.ID(u.ID).AllCols().Update(u)
return err
}
@ -890,7 +890,7 @@ func GetUserByKeyID(keyID int64) (*User, error) {
func getUserByID(e Engine, id int64) (*User, error) {
u := new(User)
has, err := e.Id(id).Get(u)
has, err := e.ID(id).Get(u)
if err != nil {
return nil, err
} else if !has {

4
models/user_mail.go

@ -132,7 +132,7 @@ func (email *EmailAddress) Activate() error {
}
email.IsActivated = true
if _, err := sess.Id(email.ID).AllCols().Update(email); err != nil {
if _, err := sess.ID(email.ID).AllCols().Update(email); err != nil {
return err
} else if err = updateUser(sess, user); err != nil {
return err
@ -202,7 +202,7 @@ func MakeEmailPrimary(email *EmailAddress) error {
}
user.Email = email.Email
if _, err = sess.Id(user.ID).AllCols().Update(user); err != nil {
if _, err = sess.ID(user.ID).AllCols().Update(user); err != nil {
return err
}

2
models/webhook.go

@ -654,6 +654,8 @@ func (t *HookTask) deliver() {
timeout := time.Duration(setting.Webhook.DeliverTimeout) * time.Second
req := httplib.Post(t.URL).SetTimeout(timeout, timeout).
Header("X-Github-Delivery", t.UUID).
Header("X-Github-Event", string(t.EventType)).
Header("X-Gogs-Delivery", t.UUID).
Header("X-Gogs-Signature", t.Signature).
Header("X-Gogs-Event", string(t.EventType)).

80
pkg/bindata/bindata.go

File diff suppressed because one or more lines are too long

4
pkg/context/context.go

@ -72,6 +72,10 @@ func (c *Context) RequireAutosize() {
c.Require("Autosize")
}
func (c *Context) RequireDropzone() {
c.Require("Dropzone")
}
// FormErr sets "Err_xxx" field in template data.
func (c *Context) FormErr(names ...string) {
for i := range names {

5
pkg/markup/markup.go

@ -53,9 +53,8 @@ var (
CrossReferenceIssueNumericPattern = regexp.MustCompile(`( |^)[0-9a-zA-Z-_\.]+/[0-9a-zA-Z-_\.]+#[0-9]+\b`)
// Sha1CurrentPattern matches string that represents a commit SHA, e.g. d8a994ef243349f321568f9e36d5c3f444b99cae
// FIXME: this pattern matches pure numbers as well, right now we do a hack to check in RenderSha1CurrentPattern
// by converting string to a number.
Sha1CurrentPattern = regexp.MustCompile(`\b[0-9a-f]{40}\b`)
// FIXME: this pattern matches pure numbers as well, right now we do a hack to check in RenderSha1CurrentPattern by converting string to a number.
Sha1CurrentPattern = regexp.MustCompile(`\b[0-9a-f]{7,40}\b`)
)
// FindAllMentions matches mention patterns in given content

3
public/css/gogs.css

@ -1731,6 +1731,9 @@ footer .ui.language .menu {
margin-left: 10px;
margin-top: 10px;
}
.repository.view.issue .pull .merge.box #commit_description {
height: auto;
}
.repository.view.issue .comment-list:before {
display: block;
content: "";

15
public/js/gogs.js

@ -111,7 +111,7 @@ function initCommentForm() {
// This should be added directly to HTML but somehow just get empty <span> on this page.
$labelMenu.find('.item:not(.no-select) .octicon:not(.octicon-check)').each(function () {
$(this).html('&nbsp;');
})
});
$labelMenu.find('.item:not(.no-select)').click(function () {
if ($(this).hasClass('checked')) {
$(this).removeClass('checked');
@ -499,6 +499,15 @@ function initRepository() {
if ($('.repository.compare.pull').length > 0) {
initFilterSearchDropdown('.choose.branch .dropdown');
}
if ($('.repository.view.pull').length > 0) {
$('.comment.merge.box input[name=merge_style]').change(function () {
if ($(this).val() === 'create_merge_commit') {
$('.commit.description.field').show();
} else {
$('.commit.description.field').hide();
}
})
}
}
function initWikiForm() {
@ -1143,7 +1152,7 @@ function initWebhookSettings() {
$(document).ready(function () {
csrf = $('meta[name=_csrf]').attr("content");
suburl = $('meta[name=_suburl]').attr("content");
// Set cursor to the end of autofocus input string
$('input[autofocus]').each(function () {
$(this).val($(this).val());
@ -1469,7 +1478,7 @@ function getByteLen(normalVal) {
}
function showMessageMaxLength(maxLen, textElemId, counterId) {
var $msg = $('#'+textElemId);
var $msg = $('#'+textElemId);
$('#'+counterId).html(maxLen - getByteLen($msg.val()));
var onMessageKey = function (e) {

3
public/less/_repository.less

@ -639,6 +639,9 @@
margin-left: 10px;
margin-top: 10px;
}
#commit_description {
height: auto;
}
}
}
.comment-list {

18
routes/repo/commit.go

@ -121,8 +121,8 @@ func FileHistory(c *context.Context) {
}
func Diff(c *context.Context) {
c.Data["PageIsDiff"] = true
c.Data["RequireHighlightJS"] = true
c.PageIs("Diff")
c.RequireHighlightJS()
userName := c.Repo.Owner.Name
repoName := c.Repo.Repository.Name
@ -130,11 +130,7 @@ func Diff(c *context.Context) {
commit, err := c.Repo.GitRepo.GetCommit(commitID)
if err != nil {
if git.IsErrNotExist(err) {
c.Handle(404, "Repo.GitRepo.GetCommit", err)
} else {
c.Handle(500, "Repo.GitRepo.GetCommit", err)
}
c.NotFoundOrServerError("get commit by ID", git.IsErrNotExist, err)
return
}
@ -142,7 +138,7 @@ func Diff(c *context.Context) {
commitID, setting.Git.MaxGitDiffLines,
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles)
if err != nil {
c.NotFoundOrServerError("GetDiffCommit", git.IsErrNotExist, err)
c.NotFoundOrServerError("get diff commit", git.IsErrNotExist, err)
return
}
@ -151,7 +147,7 @@ func Diff(c *context.Context) {
sha, err := commit.ParentID(i)
parents[i] = sha.String()
if err != nil {
c.Handle(404, "repo.Diff", err)
c.NotFound()
return
}
}
@ -161,12 +157,12 @@ func Diff(c *context.Context) {
return
}
c.Title(commit.Summary() + " · " + tool.ShortSHA1(commitID))
c.Data["CommitID"] = commitID
c.Data["IsSplitStyle"] = c.Query("style") == "split"
c.Data["Username"] = userName
c.Data["Reponame"] = repoName
c.Data["IsImageFile"] = commit.IsImageFile
c.Data["Title"] = commit.Summary() + " · " + tool.ShortSHA1(commitID)
c.Data["Commit"] = commit
c.Data["Author"] = models.ValidateCommitWithEmail(commit)
c.Data["Diff"] = diff
@ -177,7 +173,7 @@ func Diff(c *context.Context) {
c.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", parents[0])
}
c.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "raw", commitID)
c.HTML(200, DIFF)
c.Success(DIFF)
}
func RawDiff(c *context.Context) {

41
routes/repo/editor.go

@ -15,6 +15,7 @@ import (
"github.com/gogs/git-module"
"github.com/gogs/gogs/models"
"github.com/gogs/gogs/models/errors"
"github.com/gogs/gogs/pkg/context"
"github.com/gogs/gogs/pkg/form"
"github.com/gogs/gogs/pkg/setting"
@ -89,7 +90,7 @@ func editFile(c *context.Context, isNewFile bool) {
buf = append(buf, d...)
if err, content := template.ToUTF8WithErr(buf); err != nil {
if err != nil {
log.Error(2, "ToUTF8WithErr: %v", err)
log.Error(2, "Failed to convert encoding to UTF-8: %v", err)
}
c.Data["FileContent"] = string(buf)
} else {
@ -276,8 +277,9 @@ func editFilePost(c *context.Context, f form.EditRepoFile, isNewFile bool) {
Content: strings.Replace(f.Content, "\r", "", -1),
IsNewFile: isNewFile,
}); err != nil {
log.Error(2, "Failed to update repo file: %v", err)
c.FormErr("TreePath")
c.RenderWithErr(c.Tr("repo.editor.fail_to_update_file", f.TreePath, err), EDIT_FILE, &f)
c.RenderWithErr(c.Tr("repo.editor.fail_to_update_file", f.TreePath, errors.InternalServerError), EDIT_FILE, &f)
return
}
@ -324,18 +326,18 @@ func DiffPreviewPost(c *context.Context, f form.EditPreviewDiff) {
}
func DeleteFile(c *context.Context) {
c.Data["PageIsDelete"] = true
c.PageIs("Delete")
c.Data["BranchLink"] = c.Repo.RepoLink + "/src/" + c.Repo.BranchName
c.Data["TreePath"] = c.Repo.TreePath
c.Data["commit_summary"] = ""
c.Data["commit_message"] = ""
c.Data["commit_choice"] = "direct"
c.Data["new_branch_name"] = ""
c.HTML(200, DELETE_FILE)
c.Success(DELETE_FILE)
}
func DeleteFilePost(c *context.Context, f form.DeleteRepoFile) {
c.Data["PageIsDelete"] = true
c.PageIs("Delete")
c.Data["BranchLink"] = c.Repo.RepoLink + "/src/" + c.Repo.BranchName
c.Data["TreePath"] = c.Repo.TreePath
@ -351,13 +353,13 @@ func DeleteFilePost(c *context.Context, f form.DeleteRepoFile) {
c.Data["new_branch_name"] = branchName
if c.HasError() {
c.HTML(200, DELETE_FILE)
c.Success(DELETE_FILE)
return
}
if oldBranchName != branchName {
if _, err := c.Repo.Repository.GetBranch(branchName); err == nil {
c.Data["Err_NewBranchName"] = true
c.FormErr("NewBranchName")
c.RenderWithErr(c.Tr("repo.editor.branch_already_exists", branchName), DELETE_FILE, &f)
return
}
@ -380,7 +382,8 @@ func DeleteFilePost(c *context.Context, f form.DeleteRepoFile) {
TreePath: c.Repo.TreePath,
Message: message,
}); err != nil {
c.Handle(500, "DeleteRepoFile", err)
log.Error(2, "Failed to delete repo file: %v", err)
c.RenderWithErr(c.Tr("repo.editor.fail_to_delete_file", c.Repo.TreePath, errors.InternalServerError), DELETE_FILE, &f)
return
}
@ -393,14 +396,14 @@ func DeleteFilePost(c *context.Context, f form.DeleteRepoFile) {
}
func renderUploadSettings(c *context.Context) {
c.Data["RequireDropzone"] = true
c.RequireDropzone()
c.Data["UploadAllowedTypes"] = strings.Join(setting.Repository.Upload.AllowedTypes, ",")
c.Data["UploadMaxSize"] = setting.Repository.Upload.FileMaxSize
c.Data["UploadMaxFiles"] = setting.Repository.Upload.MaxFiles
}
func UploadFile(c *context.Context) {
c.Data["PageIsUpload"] = true
c.PageIs("Upload")
renderUploadSettings(c)
treeNames, treePaths := getParentTreeFields(c.Repo.TreePath)
@ -416,12 +419,11 @@ func UploadFile(c *context.Context) {
c.Data["commit_message"] = ""
c.Data["commit_choice"] = "direct"
c.Data["new_branch_name"] = ""
c.HTML(200, UPLOAD_FILE)
c.Success(UPLOAD_FILE)
}
func UploadFilePost(c *context.Context, f form.UploadRepoFile) {
c.Data["PageIsUpload"] = true
c.PageIs("Upload")
renderUploadSettings(c)
oldBranchName := c.Repo.BranchName
@ -448,13 +450,13 @@ func UploadFilePost(c *context.Context, f form.UploadRepoFile) {
c.Data["new_branch_name"] = branchName
if c.HasError() {
c.HTML(200, UPLOAD_FILE)
c.Success(UPLOAD_FILE)
return
}
if oldBranchName != branchName {
if _, err := c.Repo.Repository.GetBranch(branchName); err == nil {
c.Data["Err_NewBranchName"] = true
c.FormErr("NewBranchName")
c.RenderWithErr(c.Tr("repo.editor.branch_already_exists", branchName), UPLOAD_FILE, &f)
return
}
@ -470,13 +472,13 @@ func UploadFilePost(c *context.Context, f form.UploadRepoFile) {
break
}
c.Handle(500, "Repo.Commit.GetTreeEntryByPath", err)
c.ServerError("GetTreeEntryByPath", err)
return
}
// User can only upload files to a directory.
if !entry.IsDir() {
c.Data["Err_TreePath"] = true
c.FormErr("TreePath")
c.RenderWithErr(c.Tr("repo.editor.directory_is_a_file", part), UPLOAD_FILE, &f)
return
}
@ -500,8 +502,9 @@ func UploadFilePost(c *context.Context, f form.UploadRepoFile) {
Message: message,
Files: f.Files,
}); err != nil {
c.Data["Err_TreePath"] = true
c.RenderWithErr(c.Tr("repo.editor.unable_to_upload_files", f.TreePath, err), UPLOAD_FILE, &f)
log.Error(2, "Failed to upload files: %v", err)
c.FormErr("TreePath")
c.RenderWithErr(c.Tr("repo.editor.unable_to_upload_files", f.TreePath, errors.InternalServerError), UPLOAD_FILE, &f)
return
}

38
routes/repo/http.go

@ -17,7 +17,6 @@ import (
"strings"
"time"
"github.com/Unknwon/com"
log "gopkg.in/clog.v1"
"gopkg.in/macaron.v1"
@ -28,17 +27,6 @@ import (
"github.com/gogs/gogs/pkg/tool"
)
const (
ENV_AUTH_USER_ID = "GOGS_AUTH_USER_ID"
ENV_AUTH_USER_NAME = "GOGS_AUTH_USER_NAME"
ENV_AUTH_USER_EMAIL = "GOGS_AUTH_USER_EMAIL"
ENV_REPO_OWNER_NAME = "GOGS_REPO_OWNER_NAME"
ENV_REPO_OWNER_SALT_MD5 = "GOGS_REPO_OWNER_SALT_MD5"
ENV_REPO_ID = "GOGS_REPO_ID"
ENV_REPO_NAME = "GOGS_REPO_NAME"
ENV_REPO_CUSTOM_HOOKS_PATH = "GOGS_REPO_CUSTOM_HOOKS_PATH"
)
type HTTPContext struct {
*context.Context
OwnerName string
@ -228,30 +216,6 @@ func (h *serviceHandler) sendFile(contentType string) {
http.ServeFile(h.w, h.r, reqFile)
}
type ComposeHookEnvsOptions struct {
AuthUser *models.User
OwnerName string
OwnerSalt string
RepoID int64
RepoName string
RepoPath string
}
func ComposeHookEnvs(opts ComposeHookEnvsOptions) []string {
envs := []string{
"SSH_ORIGINAL_COMMAND=1",
ENV_AUTH_USER_ID + "=" + com.ToStr(opts.AuthUser.ID),
ENV_AUTH_USER_NAME + "=" + opts.AuthUser.Name,
ENV_AUTH_USER_EMAIL + "=" + opts.AuthUser.Email,
ENV_REPO_OWNER_NAME + "=" + opts.OwnerName,
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"),
}
return envs
}
func serviceRPC(h serviceHandler, service string) {
defer h.r.Body.Close()
@ -279,7 +243,7 @@ func serviceRPC(h serviceHandler, service string) {
var stderr bytes.Buffer
cmd := exec.Command("git", service, "--stateless-rpc", h.dir)
if service == "receive-pack" {
cmd.Env = append(os.Environ(), ComposeHookEnvs(ComposeHookEnvsOptions{
cmd.Env = append(os.Environ(), models.ComposeHookEnvs(models.ComposeHookEnvsOptions{
AuthUser: h.authUser,
OwnerName: h.ownerName,
OwnerSalt: h.ownerSalt,

4
routes/repo/pull.go

@ -126,6 +126,8 @@ func ForkPost(c *context.Context, f form.CreateRepo) {
if err != nil {
c.Data["Err_RepoName"] = true
switch {
case errors.IsReachLimitOfRepo(err):
c.RenderWithErr(c.Tr("repo.form.reach_limit_of_creation", c.User.RepoCreationNum()), FORK, &f)
case models.IsErrRepoAlreadyExist(err):
c.RenderWithErr(c.Tr("repo.settings.new_owner_has_same_repo"), FORK, &f)
case models.IsErrNameReserved(err):
@ -406,7 +408,7 @@ func MergePullRequest(c *context.Context) {
pr.Issue = issue
pr.Issue.Repo = c.Repo.Repository
if err = pr.Merge(c.User, c.Repo.GitRepo, models.MergeStyle(c.Query("merge_style"))); err != nil {
if err = pr.Merge(c.User, c.Repo.GitRepo, models.MergeStyle(c.Query("merge_style")), c.Query("commit_description")); err != nil {
c.ServerError("Merge", err)
return
}

1
routes/repo/setting.go

@ -44,6 +44,7 @@ func Settings(c *context.Context) {
func SettingsPost(c *context.Context, f form.RepoSetting) {
c.Title("repo.settings")
c.PageIs("SettingsOptions")
c.RequireAutosize()
repo := c.Repo.Repository

4
routes/user/auth.go

@ -73,10 +73,10 @@ func AutoLogin(c *context.Context) (bool, error) {
}
// isValidRedirect returns false if the URL does not redirect to same site.
// False: //url, http://url
// False: //url, http://url, /\url
// True: /url
func isValidRedirect(url string) bool {
return len(url) >= 2 && url[0] == '/' && url[1] != '/'
return len(url) >= 2 && url[0] == '/' && url[1] != '/' && url[1] != '\\'
}
func Login(c *context.Context) {

7
scripts/systemd/gogs.service

@ -19,5 +19,12 @@ ExecStart=/home/git/gogs/gogs web
Restart=always
Environment=USER=git HOME=/home/git
# Some distributions may not support these hardening directives. If you cannot start the service due
# to an unknown option, comment out the ones not supported by your version of systemd.
ProtectSystem=full
PrivateDevices=yes
PrivateTmp=yes
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target

2
templates/.VERSION

@ -1 +1 @@
0.11.58.0618
0.11.63.0817

8
templates/base/footer.tmpl

@ -11,9 +11,9 @@
</div>
<div class="ui right links">
{{if .ShowFooterBranding}}
<a target="_blank" href="https://github.com/gogits/gogs"><i class="fa fa-github-square"></i><span class="sr-only">GitHub</span></a>
<a target="_blank" href="https://twitter.com/GogsHQ"><i class="fa fa-twitter"></i><span class="sr-only">Twitter</span></a>
<a target="_blank" href="http://weibo.com/gogschina"><i class="fa fa-weibo"></i><span class="sr-only">Sina Weibo</span></a>
<a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs"><i class="fa fa-github-square"></i><span class="sr-only">GitHub</span></a>
<a target="_blank" rel="noopener noreferrer" href="https://twitter.com/GogsHQ"><i class="fa fa-twitter"></i><span class="sr-only">Twitter</span></a>
<a target="_blank" rel="noopener noreferrer" href="http://weibo.com/gogschina"><i class="fa fa-weibo"></i><span class="sr-only">Sina Weibo</span></a>
{{end}}
<div class="ui language bottom floating slide up dropdown link item">
<i class="world icon"></i>
@ -25,7 +25,7 @@
</div>
</div>
<a href="/assets/librejs/librejs.html" style="display:none" data-jslicense="1">Javascript Licenses</a>
<a target="_blank" href="https://gogs.io">{{.i18n.Tr "website"}}</a>
<a target="_blank" rel="noopener noreferrer" href="https://gogs.io">{{.i18n.Tr "website"}}</a>
{{if (or .ShowFooterVersion .PageIsAdmin)}}<span class="version">{{GoVer}}</span>{{end}}
</div>
</div>

4
templates/base/head.tmpl

@ -160,7 +160,7 @@
<a class="{{if .PageIsUserSettings}}active{{end}} item" href="{{AppSubURL}}/user/settings">
<i class="octicon octicon-settings"></i> {{.i18n.Tr "your_settings"}}
</a>
<a class="item" target="_blank" href="https://gogs.io/docs" rel="noreferrer">
<a class="item" target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs" rel="noreferrer">
<i class="octicon octicon-question"></i> {{.i18n.Tr "help"}}
</a>
{{if .IsAdmin}}
@ -181,7 +181,7 @@
{{else}}
<a class="main-menu item" target="_blank" href="https://gogs.io/docs" rel="noreferrer">{{.i18n.Tr "help"}}
<a class="main-menu item" target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs" rel="noreferrer">{{.i18n.Tr "help"}}
<i class="menu-icon octicon octicon-info"></i>
</a>
<div class="right menu">

54
templates/home.tmpl

@ -20,7 +20,7 @@
<i class="octicon octicon-flame"></i> Einfach zu installieren
</h1>
<p class="large">
Starte einfach <a target="_blank" href="https://gogs.io/docs/installation/install_from_binary.html">die Anwendung</a> für deine Plattform. Gogs gibt es auch für <a target="_blank" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a>, <a target="_blank" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a> oder als <a target="_blank" href="https://gogs.io/docs/installation/install_from_packages.html">Installationspaket</a>.
Starte einfach <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_binary.html">die Anwendung</a> für deine Plattform. Gogs gibt es auch für <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a>, <a target="_blank" rel="noopener noreferrer" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a> oder als <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_packages.html">Installationspaket</a>.
</p>
</div>
<div class="eight wide center column">
@ -28,7 +28,7 @@
<i class="octicon octicon-device-desktop"></i> Plattformübergreifend
</h1>
<p class="large">
Gogs läuft überall. <a target="_blank" href="http://golang.org/">Go</a> kompiliert für: Windows, macOS, Linux, ARM, etc. Wähle dasjenige System, was dir am meisten gefällt!
Gogs läuft überall. <a target="_blank" rel="noopener noreferrer" href="http://golang.org/">Go</a> kompiliert für: Windows, macOS, Linux, ARM, etc. Wähle dasjenige System, was dir am meisten gefällt!
</p>
</div>
</div>
@ -46,7 +46,7 @@
<i class="octicon octicon-code"></i> Quelloffen
</h1>
<p class="large">
Der komplette Code befindet sich auf <a target="_blank" href="https://github.com/gogits/gogs/">GitHub</a>! Unterstütze uns bei der Verbesserung dieses Projekts. Trau dich!
Der komplette Code befindet sich auf <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/">GitHub</a>! Unterstütze uns bei der Verbesserung dieses Projekts. Trau dich!
</p>
</div>
</div>
@ -57,7 +57,7 @@
<i class="octicon octicon-flame"></i> 易安装
</h1>
<p class="large">
您除了可以根据操作系统平台通过 <a target="_blank" href="https://gogs.io/docs/installation/install_from_binary.html">二进制运行</a>,还可以通过 <a target="_blank" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> 或 <a target="_blank" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>,以及 <a target="_blank" href="https://gogs.io/docs/installation/install_from_packages.html">包管理</a> 安装。
您除了可以根据操作系统平台通过 <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_binary.html">二进制运行</a>,还可以通过 <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> 或 <a target="_blank" rel="noopener noreferrer" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>,以及 <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_packages.html">包管理</a> 安装。
</p>
</div>
<div class="eight wide center column">
@ -65,7 +65,7 @@
<i class="octicon octicon-device-desktop"></i> 跨平台
</h1>
<p class="large">
任何 <a target="_blank" href="http://golang.org/">Go 语言</a> 支持的平台都可以运行 Gogs,包括 Windows、Mac、Linux 以及 ARM。挑一个您喜欢的就行!
任何 <a target="_blank" rel="noopener noreferrer" href="http://golang.org/">Go 语言</a> 支持的平台都可以运行 Gogs,包括 Windows、Mac、Linux 以及 ARM。挑一个您喜欢的就行!
</p>
</div>
</div>
@ -83,7 +83,7 @@
<i class="octicon octicon-code"></i> 开源化
</h1>
<p class="large">
所有的代码都开源在 <a target="_blank" href="https://github.com/gogits/gogs/">GitHub</a> 上,赶快加入我们来共同发展这个伟大的项目!还等什么?成为贡献者吧!
所有的代码都开源在 <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/">GitHub</a> 上,赶快加入我们来共同发展这个伟大的项目!还等什么?成为贡献者吧!
</p>
</div>
</div>
@ -94,10 +94,10 @@
<i class="octicon octicon-flame"></i> Facile à installer
</h1>
<p class="large">
Il suffit de <a target="_blank" href="https://gogs.io/docs/installation/install_from_binary.html">lancer l'exécutable</a> correspondant à votre système.
Ou d'utiliser Gogs avec <a target="_blank" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> ou
<a target="_blank" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>
ou en l'installant depuis un <a target="_blank" href="https://gogs.io/docs/installation/install_from_packages.html">package</a>.
Il suffit de <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_binary.html">lancer l'exécutable</a> correspondant à votre système.
Ou d'utiliser Gogs avec <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> ou
<a target="_blank" rel="noopener noreferrer" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>
ou en l'installant depuis un <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_packages.html">package</a>.
</p>
</div>
<div class="eight wide center column">
@ -105,7 +105,7 @@
<i class="octicon octicon-device-desktop"></i> Multi-plateforme
</h1>
<p class="large">
Gogs tourne partout où <a target="_blank" href="http://golang.org/">Go</a> peut être compilé : Windows, macOS, Linux, ARM, etc. Choisissez votre préféré !
Gogs tourne partout où <a target="_blank" rel="noopener noreferrer" href="http://golang.org/">Go</a> peut être compilé : Windows, macOS, Linux, ARM, etc. Choisissez votre préféré !
</p>
</div>
</div>
@ -123,7 +123,7 @@
<i class="octicon octicon-code"></i> Open Source
</h1>
<p class="large">
Toutes les sources sont sur <a target="_blank" href="https://github.com/gogits/gogs/">GitHub</a> ! Rejoignez-nous et contribuez à rendre ce projet encore meilleur.
Toutes les sources sont sur <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/">GitHub</a> ! Rejoignez-nous et contribuez à rendre ce projet encore meilleur.
</p>
</div>
</div>
@ -134,7 +134,7 @@
<i class="octicon octicon-flame"></i> Fácil de instalar
</h1>
<p class="large">
Simplemente <a target="_blank" href="https://gogs.io/docs/installation/install_from_binary.html">arranca el binario</a> para tu plataforma. O usa Gogs con <a target="_blank" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> o <a target="_blank" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>, o utilice el <a target="_blank" href="https://gogs.io/docs/installation/install_from_packages.html">paquete</a>.
Simplemente <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_binary.html">arranca el binario</a> para tu plataforma. O usa Gogs con <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> o <a target="_blank" rel="noopener noreferrer" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>, o utilice el <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_packages.html">paquete</a>.
</p>
</div>
<div class="eight wide center column">
@ -142,7 +142,7 @@
<i class="octicon octicon-device-desktop"></i> Multiplatforma
</h1>
<p class="large">
Gogs funciona en cualquier parte, <a target="_blank" href="http://golang.org/">Go</a> puede compilarse en: Windows, macOS, Linux, ARM, etc. !Elige tu favorita!
Gogs funciona en cualquier parte, <a target="_blank" rel="noopener noreferrer" href="http://golang.org/">Go</a> puede compilarse en: Windows, macOS, Linux, ARM, etc. !Elige tu favorita!
</p>
</div>
</div>
@ -160,7 +160,7 @@
<i class="octicon octicon-code"></i> Open Source
</h1>
<p class="large">
¡Está todo en <a target="_blank" href="https://github.com/gogits/gogs/">GitHub</a>! Uniros contribuyendo a hacer este proyecto todavía mejor. ¡No seas tímido y colabora!
¡Está todo en <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/">GitHub</a>! Uniros contribuyendo a hacer este proyecto todavía mejor. ¡No seas tímido y colabora!
</p>
</div>
</div>
@ -171,7 +171,7 @@
<i class="octicon octicon-flame"></i> Fácil de instalar
</h1>
<p class="large">
Simplesmente <a target="_blank" href="https://gogs.io/docs/installation/install_from_binary.html">rode o executável</a> para o seu sistema operacional. Ou obtenha o Gogs com o <a target="_blank" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> ou <a target="_blank" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>, ou baixe o <a target="_blank" href="https://gogs.io/docs/installation/install_from_packages.html">pacote</a>.
Simplesmente <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_binary.html">rode o executável</a> para o seu sistema operacional. Ou obtenha o Gogs com o <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> ou <a target="_blank" rel="noopener noreferrer" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>, ou baixe o <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_packages.html">pacote</a>.
</p>
</div>
<div class="eight wide center column">
@ -179,7 +179,7 @@
<i class="octicon octicon-device-desktop"></i> Multi-plataforma
</h1>
<p class="large">
Gogs roda em qualquer sistema operacional em que <a target="_blank" href="http://golang.org/">Go</a> consegue compilar: Windows, macOS, Linux, ARM, etc. Escolha qual você gosta mais!
Gogs roda em qualquer sistema operacional em que <a target="_blank" rel="noopener noreferrer" href="http://golang.org/">Go</a> consegue compilar: Windows, macOS, Linux, ARM, etc. Escolha qual você gosta mais!
</p>
</div>
</div>
@ -197,7 +197,7 @@
<i class="octicon octicon-code"></i> Código aberto
</h1>
<p class="large">
Está tudo no <a target="_blank" href="https://github.com/gogits/gogs/">GitHub</a>! Contribua e torne este projeto ainda melhor. Não tenha vergonha de contribuir!
Está tudo no <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/">GitHub</a>! Contribua e torne este projeto ainda melhor. Não tenha vergonha de contribuir!
</p>
</div>
</div>
@ -208,7 +208,7 @@
<i class="octicon octicon-flame"></i> Простой в установке
</h1>
<p class="large">
Просто <a target="_blank" href="https://gogs.io/docs/installation/install_from_binary.html">запустите исполняемый файл</a> для вашей платформы. Используйте Gogs с <a target="_blank" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> или <a target="_blank" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>, или загрузите <a target="_blank" href="https://gogs.io/docs/installation/install_from_packages.html">пакет</a>.
Просто <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_binary.html">запустите исполняемый файл</a> для вашей платформы. Используйте Gogs с <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> или <a target="_blank" rel="noopener noreferrer" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>, или загрузите <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_packages.html">пакет</a>.
</p>
</div>
<div class="eight wide center column">
@ -216,7 +216,7 @@
<i class="octicon octicon-device-desktop"></i> Кроссплатформенный
</h1>
<p class="large">
Gogs работает на любой операционной системе, которая может компилировать <a target="_blank" href="http://golang.org/">Go</a>: Windows, macOS, Linux, ARM и т. д. Выбирайте, что вам больше нравится!
Gogs работает на любой операционной системе, которая может компилировать <a target="_blank" rel="noopener noreferrer" href="http://golang.org/">Go</a>: Windows, macOS, Linux, ARM и т. д. Выбирайте, что вам больше нравится!
</p>
</div>
</div>
@ -234,7 +234,7 @@
<i class="octicon octicon-code"></i> Открытый исходный код
</h1>
<p class="large">
Всё это на <a target="_blank" href="https://github.com/gogits/gogs/">GitHub</a>! Присоединяйтесь к нам, внося вклад, чтобы сделать этот проект еще лучше. Не бойтесь помогать!
Всё это на <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/">GitHub</a>! Присоединяйтесь к нам, внося вклад, чтобы сделать этот проект еще лучше. Не бойтесь помогать!
</p>
</div>
</div>
@ -245,7 +245,7 @@
<i class="octicon octicon-flame"></i> Простий у втановленні
</h1>
<p class="large">
Просто <a target="_blank" href="https://gogs.io/docs/installation/install_from_binary.html">запустіть виконуваний файл</a> для вашої платформи. Використовуйте Gogs с <a target="_blank" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> або <a target="_blank" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>, або завантажте <a target="_blank" href="https://gogs.io/docs/installation/install_from_packages.html">пакет</a>.
Просто <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_binary.html">запустіть виконуваний файл</a> для вашої платформи. Використовуйте Gogs с <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> або <a target="_blank" rel="noopener noreferrer" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>, або завантажте <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_packages.html">пакет</a>.
</p>
</div>
<div class="eight wide center column">
@ -253,7 +253,7 @@
<i class="octicon octicon-device-desktop"></i> Кросплатформність
</h1>
<p class="large">
Gogs працює у будь-якій операційній системі, що може компілювати <a target="_blank" href="http://golang.org/">Go</a>: Windows, macOS, Linux, ARM і т. д. Обирайте що вам більше до вподоби!
Gogs працює у будь-якій операційній системі, що може компілювати <a target="_blank" rel="noopener noreferrer" href="http://golang.org/">Go</a>: Windows, macOS, Linux, ARM і т. д. Обирайте що вам більше до вподоби!
</p>
</div>
</div>
@ -271,7 +271,7 @@
<i class="octicon octicon-code"></i> Відкритий сирцевий код
</h1>
<p class="large">
Все це у <a target="_blank" href="https://github.com/gogits/gogs/">GitHub</a>! Приєднуйтеся до нас, робіть внесок, щоб зробити цей проект ще краще. Не бійтеся допомагати!
Все це у <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/">GitHub</a>! Приєднуйтеся до нас, робіть внесок, щоб зробити цей проект ще краще. Не бійтеся допомагати!
</p>
</div>
</div>
@ -282,7 +282,7 @@
<i class="octicon octicon-flame"></i> Easy to install
</h1>
<p class="large">
Simply <a target="_blank" href="https://gogs.io/docs/installation/install_from_binary.html">run the binary</a> for your platform. Or ship Gogs with <a target="_blank" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> or <a target="_blank" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>, or get it <a target="_blank" href="https://gogs.io/docs/installation/install_from_packages.html">packaged</a>.
Simply <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_binary.html">run the binary</a> for your platform. Or ship Gogs with <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/tree/master/docker">Docker</a> or <a target="_blank" rel="noopener noreferrer" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a>, or get it <a target="_blank" rel="noopener noreferrer" href="https://gogs.io/docs/installation/install_from_packages.html">packaged</a>.
</p>
</div>
<div class="eight wide center column">
@ -290,7 +290,7 @@
<i class="octicon octicon-device-desktop"></i> Cross-platform
</h1>
<p class="large">
Gogs runs anywhere <a target="_blank" href="http://golang.org/">Go</a> can compile for: Windows, macOS, Linux, ARM, etc. Choose the one you love!
Gogs runs anywhere <a target="_blank" rel="noopener noreferrer" href="http://golang.org/">Go</a> can compile for: Windows, macOS, Linux, ARM, etc. Choose the one you love!
</p>
</div>
</div>
@ -308,7 +308,7 @@
<i class="octicon octicon-code"></i> Open Source
</h1>
<p class="large">
It's all on <a target="_blank" href="https://github.com/gogits/gogs/">GitHub</a>! Join us by contributing to make this project even better. Don't be shy to be a contributor!
It's all on <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/gogs/">GitHub</a>! Join us by contributing to make this project even better. Don't be shy to be a contributor!
</p>
</div>
</div>

2
templates/mail/auth/activate.tmpl

@ -10,6 +10,6 @@
<p>Please click the following link to verify your e-mail address within <b>{{.ActiveCodeLives}} hours</b>:</p>
<p><a href="{{AppURL}}user/activate?code={{.Code}}">{{AppURL}}user/activate?code={{.Code}}</a></p>
<p>Not working? Try copying and pasting it to your browser.</p>
<p>© 2018 <a target="_blank" href="{{AppURL}}">{{AppName}}</a></p>
<p>© 2018 <a target="_blank" rel="noopener noreferrer" href="{{AppURL}}">{{AppName}}</a></p>
</body>
</html>

2
templates/mail/auth/activate_email.tmpl

@ -10,6 +10,6 @@
<p>Please click the following link to verify your email address within <b>{{.ActiveCodeLives}} hours</b>:</p>
<p><a href="{{AppURL}}user/activate_email?code={{.Code}}&email={{.Email}}">{{AppURL}}user/activate_email?code={{.Code}}&email={{.Email}}</a></p>
<p>Not working? Try copying and pasting it to your browser.</p>
<p>© 2018 <a target="_blank" href="{{AppURL}}">{{AppName}}</a></p>
<p>© 2018 <a target="_blank" rel="noopener noreferrer" href="{{AppURL}}">{{AppName}}</a></p>
</body>
</html>

2
templates/mail/auth/register_notify.tmpl

@ -9,6 +9,6 @@
<p>Hi <b>{{.Username}}</b>, this is your registration confirmation email for {{AppName}}!</p>
<p>You can now login via username: {{.Username}}.</p>
<p><a href="{{AppURL}}user/login">{{AppURL}}user/login</a></p>
<p>© 2018 <a target="_blank" href="{{AppURL}}">{{AppName}}</a></p>
<p>© 2018 <a target="_blank" rel="noopener noreferrer" href="{{AppURL}}">{{AppName}}</a></p>
</body>
</html>

2
templates/mail/auth/reset_passwd.tmpl

@ -10,6 +10,6 @@
<p>Please click the following link to verify your email address within <b>{{.ResetPwdCodeLives}} hours</b>:</p>
<p><a href="{{AppURL}}user/reset_password?code={{.Code}}">{{AppURL}}user/reset_password?code={{.Code}}</a></p>
<p>Not working? Try copying and pasting it to your browser.</p>
<p>© 2018 <a target="_blank" href="{{AppURL}}">{{AppName}}</a></p>
<p>© 2018 <a target="_blank" rel="noopener noreferrer" href="{{AppURL}}">{{AppName}}</a></p>
</body>
</html>

2
templates/org/home.tmpl

@ -12,7 +12,7 @@
{{if .Org.Description}}<p class="desc">{{.Org.Description}}</p>{{end}}
<div class="text grey meta">
{{if .Org.Location}}<div class="item"><span class="octicon octicon-location"></span> <span>{{.Org.Location}}</span></div>{{end}}
{{if .Org.Website}}<div class="item"><span class="octicon octicon-link"></span> <a target="_blank" href="{{.Org.Website}}">{{.Org.Website}}</a></div>{{end}}
{{if .Org.Website}}<div class="item"><span class="octicon octicon-link"></span> <a target="_blank" rel="noopener noreferrer" href="{{.Org.Website}}">{{.Org.Website}}</a></div>{{end}}
</div>
</div>

2
templates/repo/create.tmpl

@ -85,7 +85,7 @@
</div>
<div class="inline field">
<label>{{.i18n.Tr "repo.readme"}} <a target="_blank" href="https://github.com/gogits/go-gogs-client/wiki/Repositories#litte-notes-on-readme-template"><span class="octicon octicon-question"></span></a></label>
<label>{{.i18n.Tr "repo.readme"}} <a target="_blank" rel="noopener noreferrer" href="https://github.com/gogits/go-gogs-client/wiki/Repositories#litte-notes-on-readme-template"><span class="octicon octicon-question"></span></a></label>
<div class="ui selection dropdown">
<input type="hidden" name="readme" value="{{.readme}}">
<div class="default text">{{.i18n.Tr "repo.readme_helper"}}</div>

2
templates/repo/header.tmpl

@ -14,7 +14,7 @@
<a href="{{AppSubURL}}/{{.Owner.Name}}">{{.Owner.Name}}</a>
<div class="divider"> / </div>
<a href="{{$.RepoLink}}">{{.Name}}</a>
{{if .IsMirror}}<div class="fork-flag">{{$.i18n.Tr "repo.mirror_from"}} <a target="_blank" href="{{$.Mirror.Address}}">{{$.Mirror.Address}}</a></div>{{end}}
{{if .IsMirror}}<div class="fork-flag">{{$.i18n.Tr "repo.mirror_from"}} <a target="_blank" rel="noopener noreferrer" href="{{$.Mirror.Address}}">{{$.Mirror.Address}}</a></div>{{end}}
{{if .IsFork}}<div class="fork-flag">{{$.i18n.Tr "repo.forked_from"}} <a href="{{.BaseRepo.Link}}">{{SubStr .BaseRepo.RelLink 1 -1}}</a></div>{{end}}
</div>

2
templates/repo/issue/labels.tmpl

@ -43,7 +43,7 @@
<div class="ui attached left aligned segment">
<h4 class="ui header">
{{.i18n.Tr "repo.issues.label_templates.title"}}
<a target="_blank"
<a target="_blank" rel="noopener noreferrer"
href="https://discuss.gogs.io/t/how-to-use-predefined-label-templates/599">
<span class="octicon octicon-question"></span>
</a>

10
templates/repo/issue/view_content.tmpl

@ -41,7 +41,7 @@
<div class="ui bottom attached segment">
<div class="ui small images">
{{range .Issue.Attachments}}
<a target="_blank" href="{{AppSubURL}}/attachments/{{.UUID}}">
<a target="_blank" rel="noopener noreferrer" href="{{AppSubURL}}/attachments/{{.UUID}}">
{{if FilenameIsImage .Name}}
<img class="ui image" src="{{AppSubURL}}/attachments/{{.UUID}}" title='{{$.i18n.Tr "repo.issues.attachment.open_tab" .Name}}'>
{{else}}
@ -102,7 +102,7 @@
<div class="ui bottom attached segment">
<div class="ui small images">
{{range .Attachments}}
<a target="_blank" href="{{AppSubURL}}/attachments/{{.UUID}}">
<a target="_blank" rel="noopener noreferrer" href="{{AppSubURL}}/attachments/{{.UUID}}">
{{if FilenameIsImage .Name}}
<img class="ui image" src="{{AppSubURL}}/attachments/{{.UUID}}" title='{{$.i18n.Tr "repo.issues.attachment.open_tab" .Name}}'>
{{else}}
@ -209,6 +209,12 @@
</div>
</div>
{{end}}
<div class="commit description field">
<div class="ui top">
<p>{{$.i18n.Tr "repo.pulls.commit_description"}}:</p>
<textarea id="commit_description" name="commit_description" tabindex="4" rows="3"></textarea>
</div>
</div>
<button class="ui green button">
<span class="octicon octicon-git-merge"></span> {{$.i18n.Tr "repo.pulls.merge_pull_request"}}
</button>

2
templates/repo/release/new.tmpl

@ -55,7 +55,7 @@
{{range .attachments}}
<tr>
<td>
<a target="_blank" href="{{AppSubURL}}/attachments/{{.UUID}}" rel="nofollow">{{.Name}}</a>
<a target="_blank" rel="noopener noreferrer" href="{{AppSubURL}}/attachments/{{.UUID}}" rel="nofollow">{{.Name}}</a>
<a class="ui text red right delete-attachment-button" href="#"><i class="octicon octicon-x" data-uuid="{{.UUID}}"></i></a>
<input name="files" type="hidden" value="{{.UUID}}">
</td>

2
templates/repo/user_cards.tmpl

@ -12,7 +12,7 @@
<div class="meta">
{{if .Website}}
<span class="octicon octicon-link"></span> <a href="{{.Website}}" target="_blank">{{.Website}}</a>
<span class="octicon octicon-link"></span> <a href="{{.Website}}" target="_blank" rel="noopener noreferrer">{{.Website}}</a>
{{else if .Location}}
<span class="octicon octicon-location"></span> {{.Location}}
{{else}}

2
templates/user/profile.tmpl

@ -31,7 +31,7 @@
{{if .Owner.Website}}
<li>
<i class="octicon octicon-link"></i>
<a target="_blank" href="{{.Owner.Website}}">{{.Owner.Website}}</a>
<a target="_blank" rel="noopener noreferrer" href="{{.Owner.Website}}">{{.Owner.Website}}</a>
</li>
{{end}}
<li><i class="octicon octicon-clock"></i> {{.i18n.Tr "user.join_on"}} {{DateFmtShort .Owner.Created}}</li>

2
vendor/github.com/gogs/git-module/git.go generated vendored

@ -10,7 +10,7 @@ import (
"time"
)
const _VERSION = "0.6.7"
const _VERSION = "0.7.0"
func Version() string {
return _VERSION

9
vendor/github.com/gogs/git-module/repo.go generated vendored

@ -176,10 +176,15 @@ func Pull(repoPath string, opts PullRemoteOptions) error {
return err
}
// PushWithEnvs pushs local commits to given remote branch with given environment variables.
func PushWithEnvs(repoPath, remote, branch string, envs []string) error {
_, err := NewCommand("push", remote, branch).AddEnvs(envs...).RunInDir(repoPath)
return err
}
// Push pushs local commits to given remote branch.
func Push(repoPath, remote, branch string) error {
_, err := NewCommand("push", remote, branch).RunInDir(repoPath)
return err
return PushWithEnvs(repoPath, remote, branch, nil)
}
type CheckoutOptions struct {

2
vendor/github.com/gogs/git-module/repo_commit.go generated vendored

@ -129,7 +129,7 @@ func (repo *Repository) GetCommit(commitID string) (*Commit, error) {
var err error
commitID, err = GetFullCommitID(repo.Path, commitID)
if err != nil {
return nil, fmt.Errorf("GetCommitFullID: %v", err)
return nil, err
}
id, err := NewIDFromString(commitID)
if err != nil {

4
vendor/github.com/gogs/git-module/repo_tag.go generated vendored

@ -95,7 +95,7 @@ func (repo *Repository) GetTag(name string) (*Tag, error) {
// GetTags returns all tags of the repository.
func (repo *Repository) GetTags() ([]string, error) {
cmd := NewCommand("tag", "-l")
if version.Compare(gitVersion, "2.0.0", ">=") {
if version.Compare(gitVersion, "2.4.9", ">=") {
cmd.AddArguments("--sort=-v:taggerdate")
}
@ -107,7 +107,7 @@ func (repo *Repository) GetTags() ([]string, error) {
tags := strings.Split(stdout, "\n")
tags = tags[:len(tags)-1]
if version.Compare(gitVersion, "2.0.0", "<") {
if version.Compare(gitVersion, "2.4.9", "<") {
version.Sort(tags)
// Reverse order

6
vendor/vendor.json vendored

@ -207,10 +207,10 @@
"revisionTime": "2017-03-01T03:54:11Z"
},
{
"checksumSHA1": "8KekujhL9uUvM97PP6jToeeQi6M=",
"checksumSHA1": "Ecc6Aicvu7GZe/cTRgG2TxQtOW4=",
"path": "github.com/gogs/git-module",
"revision": "abc97c40967942aec90e470834436ff69e1888f2",
"revisionTime": "2018-06-09T01:58:34Z"
"revision": "e55accd068eac1c9803754a776c22b1aeddc4602",
"revisionTime": "2018-08-17T15:03:56Z"
},
{
"checksumSHA1": "MLO0PyrK2MUO6A7Z9PxWuu43C/A=",

Loading…
Cancel
Save