Compare commits

..

245 Commits

Author SHA1 Message Date
Andrey Nering
7da3f899a6 First version of page to see notifications 2016-12-10 17:29:20 -02:00
Andrey Nering
a9844aeb8d Register notification router 2016-12-10 14:08:59 -02:00
Andrey Nering
fedf445f6a Notification item on menu 2016-12-10 14:08:59 -02:00
Andrey Nering
f692adea69 First version of notification service 2016-12-10 14:08:59 -02:00
Andrey Nering
679d91afdf Fix SQLs 2016-12-10 14:08:59 -02:00
Andrey Nering
8a3c856b1c Also create notification while commenting on issue 2016-12-10 14:08:59 -02:00
Andrey Nering
c3810c6d43 Lint 2016-12-10 14:08:59 -02:00
Andrey Nering
75c2752ee6 Use own type (smallint on DB) and iota instead of VARCHAR(1) 2016-12-10 14:08:59 -02:00
Andrey Nering
b19ec55338 Creating notifications on new issue 2016-12-10 14:08:59 -02:00
Andrey Nering
0f1b484e9a Create notification model/table 2016-12-10 14:08:59 -02:00
Bwko
cbcb4361d5 Fixes issue #283
Delete old temp local copy before we create a new temp local copy
2016-12-09 20:13:48 +01:00
Ethan Koenig
7b5b5178e1 Bug fix for edit-hook API endpoint 2016-12-09 20:11:56 +01:00
Henning Henkel
bab737bf02 Fix alignment of tooltip and add bindata - related to #359 (#364) 2016-12-08 20:59:47 +08:00
Ethan Koenig
401a8db0ed Remove stale comment in models/repo.go (#366) 2016-12-08 00:04:12 +01:00
Bwko
39d0db52de Fix for #361, renamed username to login 2016-12-07 15:56:43 +01:00
Ethan Koenig
04b9a7e7a2 Bug fixes for repo permissions in API
Also move duplicated code into repo.APIFormat(..)
2016-12-07 12:55:24 +01:00
Henning Henkel
08b9af9ad8 Added download tooltip - solves #221 (#359) 2016-12-07 09:38:20 +01:00
Bwko
026ad4aee7 Fixes panic when there's no user initialized (#358) 2016-12-06 21:58:34 +01:00
Thomas Boerger
83ed234472 Integrate templates into bindata optionally (#314)
Integrated optional bindata for the templates
2016-12-06 18:58:31 +01:00
Kim "BKC" Carlbäcker
1b5b297c39 Actually fix 'make build' (#353)
* Actually fix bloddy 'make build'
2016-12-05 18:35:22 +01:00
Thomas Boerger
2b63f32b8a Enabled bindata build tag and generate bindata (#352) 2016-12-05 23:39:45 +08:00
Kim "BKC" Carlbäcker
cd0ce9f3d8 Awlays build, even when it thinks it's up to date (#351) 2016-12-05 22:58:04 +08:00
Thomas Boerger
70134323d1 Merge pull request #348 from tboerger/release-fixes
Fix drone release publishing and test steps
2016-12-05 14:49:00 +01:00
Thomas Boerger
8a28130540 Fixed build tags and deps for all build/test steps 2016-12-05 14:34:55 +01:00
Thomas Boerger
e52b24ad5d Properly move releases within drone builds 2016-12-05 14:31:49 +01:00
Antonio Facciolo
947d2ee21b Fixes #316
Export Pusher name as GITEA_PUSHER_NAME env variable
Export also GITEA_UUID, but keep the uuid env variable for backward compatibility

export pusher name ENV variable #316

change env variable prefix to GITEA_

Signed-off-by: Antonio Facciolo <afdev82@gmail.com>

Export also GITEA_UUID #316

Keep uuid env variable for backward compatibility
2016-12-05 12:25:45 +01:00
Kim "BKC" Carlbäcker
d07c955e2a Fix regression in PR-API #248 (#349)
* Fix #344 (regression in PR-API #248)
2016-12-05 12:17:39 +01:00
Thomas Boerger
edae0f134c Merge pull request #347 from thehowl/fix-contributing-typos
Fix typos in CONTRIBUTING
2016-12-05 08:22:16 +01:00
Morgan Bazalgette
db29855d2d Apply suggested changes 2016-12-04 22:50:36 +01:00
Morgan Bazalgette
e6cb9a7397 Fix typos in CONTRIBUTING
Signed-off-by: Morgan Bazalgette <the@howl.moe>
2016-12-04 20:56:21 +01:00
Andrey Nering
dc14d0c046 Merge pull request #345 from Bwko/fix_for_320
Fix for #320
2016-12-03 20:06:05 -02:00
Bwko
0118b275b6 Fix for #320
Suppress the error when we're removing a file that may not exist
2016-12-03 22:31:54 +01:00
Denis Denisov
c8f300b2cd Safe compare password (timing attack) (#338) 2016-12-03 13:49:17 +08:00
Thomas Boerger
db6a4e9fbf Merge pull request #334 from avelino/scripts_project_name_update
Fixed project name on scripts
2016-12-02 20:13:20 +01:00
Avelino
b21bf80dd4 update SERVICENAME on init scripts 2016-12-02 15:52:28 -02:00
Kim "BKC" Carlbäcker
0f05470cb8 [API] Pull Requests (#248) 2016-12-02 12:10:39 +01:00
Kim "BKC" Carlbäcker
d7ed78a919 Merge pull request #227 from go-gitea/api/github-compliance
GitHub API Compliance Fixes
2016-12-02 10:04:15 +01:00
Kim "BKC" Carlbäcker
e8e0539b45 Linting 2016-12-02 09:31:44 +01:00
Kim "BKC" Carlbäcker
e6cfccdd40 GitHub API Compliance (& linting) 2016-12-02 09:18:15 +01:00
Kim "BKC" Carlbäcker
71bb6df75a Add undocumented endpoint for /repositories/:id 2016-12-02 09:18:15 +01:00
Avelino
bea9d55da6 Fixed project name on setting module key APP_NAME 2016-12-02 07:52:27 +01:00
Avelino
d93429af8b Fixed project name on base template head 2016-12-02 07:48:11 +01:00
Avelino
7e09f80ee3 Fixed project name on repo template mail 2016-12-02 07:46:31 +01:00
Avelino
baf60bf603 Fixed project on repo template hook settings 2016-12-02 07:46:02 +01:00
Bwko
4ff0db0246 Catch os... errors 2016-12-02 07:41:19 +01:00
Avelino
79bd7648b0 fixed typo on rename project name scripts for windows (bat) 2016-12-02 03:51:34 -02:00
Avelino
b78d3f5865 Fixed project name on scripts 2016-12-02 03:18:58 -02:00
Bwko
5ab85372da Added rel="noopener" to target="_blank" hrefs (#327)
* Added rel="noopener" to target="_blank" hrefs

* Replaced gogs.io/docs with docs.gitea.io
2016-12-02 09:12:16 +08:00
Lunny Xiao
1ae6ccb5f1 Bug fixed for .dockerignore (#329)
* bug fixed for .dockerignore

* clean up
2016-12-01 23:05:28 +08:00
Andrey Nering
0a6d9295df Merge pull request #326 from tboerger/maintainers
Added real name of Bwko to maintainers file
2016-12-01 13:03:32 -02:00
Thomas Boerger
6598745f07 Copy gitea binary to docker from correct path (#325)
Signed-off-by: Thomas Boerger <tboerger@suse.de>
2016-12-01 18:53:26 +08:00
Lunny Xiao
590a79ff8a Resolved #296 (#324)
* resolved #296

* Indentation fixed
2016-12-01 18:52:57 +08:00
Lunny Xiao
2343feadd4 resolved #310: hide fork to self (#323) 2016-12-01 18:51:50 +08:00
Thomas Boerger
bb3ed784bc Added real name of Bwko to maintainers file
Signed-off-by: Thomas Boerger <tboerger@suse.de>
2016-12-01 10:26:34 +01:00
Kim "BKC" Carlbäcker
31950cb262 Merge pull request #322 from lunny/lunny/pull_typo
typo in model/pull.go
2016-12-01 09:20:48 +01:00
Thomas Boerger
2932042a6d Get rid of bin folder within makefile, enabled TiDB (#319)
* Get rid of the bin folder within the build process

Signed-off-by: Thomas Boerger <thomas@webhippie.de>

* Dropped latest make task, it is unused

Signed-off-by: Thomas Boerger <thomas@webhippie.de>

* Added tidb tag to drone config

Signed-off-by: Thomas Boerger <thomas@webhippie.de>

* Dropped the cert build tag

Signed-off-by: Thomas Boerger <thomas@webhippie.de>

* Dropped useless minwinsvc build tag

Signed-off-by: Thomas Boerger <thomas@webhippie.de>

* Dropped the useless build tags from drone config

Signed-off-by: Thomas Boerger <thomas@webhippie.de>
2016-12-01 15:28:43 +08:00
Lunny Xiao
646e02b521 typo 2016-12-01 09:05:32 +08:00
Andrey Nering
bf0edcbdea Merge pull request #318 from stroucki/20161128locale
Suggested de locale fix
2016-11-30 19:40:29 -02:00
Michael Stroucken
4bd5730e02 Based on @tboerger's screenshot, these "times" are counts and not
clock times. Change translation to reflect that.
2016-11-30 13:25:05 -05:00
Sandro Santilli
a3fb627350 Have "make" create the executable in root dir (#247)
Same as "go build".
Makes it functional by default as it'd then find template/ and public/
by default w/out setting GITEA_WORK_DIR
2016-11-30 23:59:17 +08:00
Matthias Loibl
6dc6926abe Merge pull request #306 from Bwko/Security
Fixes xss, clickjacking & password autocompletion
2016-11-30 08:22:45 +01:00
Thomas Boerger
6519718706 Merge pull request #298 from stroucki/20161128locale
suggested locale fixes
2016-11-29 22:49:10 +01:00
Bwko
1e9730a779 Fixes xss, clickjacking & password autocompletion 2016-11-29 22:49:06 +01:00
Michael Stroucken
e929ca2c41 Time values displayed are apparently single values, so use singular. 2016-11-29 14:54:10 -05:00
Thomas Boerger
ccad2cce32 Merge pull request #275 from strk/readmelink
Turn banner into a link to the github page
2016-11-29 20:38:23 +01:00
Sandro Santilli
349ecc6919 Turn banner into a link to the github gitea repository
Also use relative link to banner
2016-11-29 18:45:02 +01:00
Thomas Boerger
b6a95a8cb3 Integrate public as bindata optionally (#293)
* Dropped unused codekit config

* Integrated dynamic and static bindata for public

* Ignore public bindata

* Add a general generate make task

* Integrated flexible public assets into web command

* Updated vendoring, added all missiong govendor deps

* Made the linter happy with the bindata and dynamic code

* Moved public bindata definition to modules directory

* Ignoring the new bindata path now

* Updated to the new public modules import path

* Updated public bindata command and drop the new prefix
2016-11-30 00:26:36 +08:00
Thomas Boerger
4680c349dd Merge pull request #303 from tboerger/linting
Fixed remaining linting errors
2016-11-29 15:18:27 +01:00
Thomas Boerger
684d55e130 Reenabled lint check within drone 2016-11-29 14:15:36 +01:00
Thomas Boerger
60e3e5b4e1 Updated bindata to latest version 2016-11-29 14:14:40 +01:00
Thomas Boerger
e93d394620 Replace invaliud bindata variable names within make task 2016-11-29 14:14:22 +01:00
Thomas Boerger
6dd2c3b2db Fixed linting errors for variable definitions 2016-11-29 14:05:26 +01:00
Kim "BKC" Carlbäcker
42ec5ce740 Fix breakage from vendor-update 2016-11-29 11:50:22 +01:00
Kim "BKC" Carlbäcker
dad806d3ea CreateBranch-hook has shasum. Use the full ref for fetching shasum 2016-11-29 11:50:22 +01:00
Kim "BKC" Carlbäcker
57dc9efaae Update gitea/sdk vendor 2016-11-29 11:50:22 +01:00
Kim "BKC" Carlbäcker
f364522468 Tag-webhooks are useless without shasums 2016-11-29 11:50:22 +01:00
Lunny Xiao
abf6c3a8e3 bug fixed caused by #295 (#299) 2016-11-29 14:57:36 +08:00
Thomas Boerger
16cdbe1956 Merge pull request #288 from tboerger/docker
Docker integration
2016-11-29 07:21:47 +01:00
Michael Stroucken
36a4663393 Rebase branch onto go-gitea/gitea 2016-11-28 20:03:45 -05:00
Andrey Nering
fd53028139 Merge pull request #294 from Bwko/Lint/user.go
Lint models/user.go
2016-11-28 20:30:02 -02:00
Andrey Nering
b9b22b4a0b Merge pull request #295 from Bwko/Lint/repo_
Lint models/repo
2016-11-28 20:29:15 -02:00
Matthias Loibl
8704f48e66 Merge pull request #290 from tboerger/maintain-contribute
Project unification, updates for contributors guide and github files
2016-11-28 20:49:39 +01:00
Bwko
bad1bc6518 Lint models/repo.go 2016-11-28 18:27:55 +01:00
Bwko
a5aae1c145 Lint models/repo_* 2016-11-28 17:58:59 +01:00
Bwko
9963d61233 Lint models/user.go 2016-11-28 17:47:46 +01:00
Thomas Boerger
d7dea676fd Added -S flag to addgroup command within Dockerfiles 2016-11-28 17:37:31 +01:00
Thomas Boerger
4b0abdae9e Replaced edge with 3.4 for the alpine base image 2016-11-28 17:23:22 +01:00
Thomas Boerger
972ce6b791 Replaced shadow with addgroup and adduser 2016-11-28 17:22:22 +01:00
Thomas Boerger
65d0426b91 Use su-exec instead of gosu, much smaller 2016-11-28 17:16:13 +01:00
Thomas Boerger
8def53ffcc Add a pragraph to the k8s PR guide to contributors guide 2016-11-28 16:57:42 +01:00
Lunny Xiao
27d66855eb golint fixed for models/migrations (#291) 2016-11-28 23:44:17 +08:00
Lunny Xiao
1d0f811399 golint fixed for models/pull.go (#292) 2016-11-28 23:31:06 +08:00
Thomas Boerger
fd3f16695e Merge pull request #289 from lunny/lunny/golint_models_issue_comment
Golint fixed for models/issue_comment.go
2016-11-28 14:46:00 +01:00
Thomas Boerger
b3abc2775f Dropped more or less useless files 2016-11-28 14:36:35 +01:00
Thomas Boerger
91d6c715ea Dropped new lines from contributing, some rewording and reformatting 2016-11-28 14:35:55 +01:00
Thomas Boerger
caac5fb99d Updated maintainers file to latest status 2016-11-28 14:35:04 +01:00
Thomas Boerger
c2044e5b39 Dropped always outdated contributors file, link to it the graph on readme 2016-11-28 14:34:06 +01:00
Lunny Xiao
9fc609ce17 golint fixed for models/issue_comment.go 2016-11-28 21:33:09 +08:00
Matthias Loibl
7b6cc9244d Update link on user’s profile avatar to avatar settings (#287) 2016-11-28 21:29:39 +08:00
Thomas Boerger
9628d4fb44 Unified GitHub templates accross all projects 2016-11-28 14:28:40 +01:00
Thomas Boerger
3d2138812c Unified editorconfig accross all projects 2016-11-28 14:27:59 +01:00
Thomas Boerger
575dc69e3b Updated drone docker definitions
In order to automatically build docker images I have re-enabled the
docker building parts within our drone runs on every push to master and
on every tag.

Signed-off-by: Thomas Boerger <tboerger@suse.de>
2016-11-28 14:15:14 +01:00
Thomas Boerger
86aa8e413a Restructured docker building
I have restructured the docker build process entirely, the binary gets
built outside of the docker build command, now we are managing all
dependencies with real Alpine packages and I have dropped features like
socat or the cron daemon.

Signed-off-by: Thomas Boerger <tboerger@suse.de>
2016-11-28 14:13:18 +01:00
Thomas Boerger
9948f0daaa Merge pull request #285 from lunny/lunny/golint_models_org_team
Golint for models/org_team.go
2016-11-28 09:42:53 +01:00
Lunny Xiao
f215d78157 rename all uID -> userID on models/org_team.go 2016-11-28 16:33:08 +08:00
Lunny Xiao
bf8d90c5cc golint fixed for models/models.go (#284) 2016-11-28 15:25:16 +08:00
Lunny Xiao
21846d16e5 golint for models/org_team.go 2016-11-28 09:30:08 +08:00
Thomas Boerger
25b5722155 Merge pull request #274 from lunny/lunny/golint_modules_auth
Golint fixed for modules/auth
2016-11-27 16:21:49 +01:00
Lunny Xiao
d0bef011ad Merge branch 'lunny/golint_modules_auth' of github.com:lunny/gitea into lunny/golint_modules_auth 2016-11-27 21:41:56 +08:00
Lunny Xiao
ec87a75c00 golint fixed for modules/auth 2016-11-27 21:39:06 +08:00
Thomas Boerger
e6da2cf2cb Merge pull request #281 from Bwko/Lint/typos
Fixes typos
2016-11-27 14:01:50 +01:00
Bwko
a4ece1f223 Fixes typos 2016-11-27 12:59:12 +01:00
Thomas Boerger
5efdccd1d8 Merge pull request #264 from Bwko/lint/org.go
Lint models/org.go
2016-11-27 12:18:20 +01:00
Thomas Boerger
7a92519bd7 Merge pull request #269 from lunny/lunny/golint_modules_log
Golint fixed for modules/log
2016-11-27 12:16:35 +01:00
Thomas Boerger
9a984c0d49 Merge pull request #266 from Bwko/lint/repo_mirror
Lint models/repo_mirror.go
2016-11-27 12:15:01 +01:00
Thomas Boerger
fe3908d099 Merge pull request #268 from Bwko/lint/repo_branch
Lint models/repo_branch.go
2016-11-27 12:14:25 +01:00
Thomas Boerger
e23a9d22e5 Merge pull request #267 from Bwko/lint/ssh_key
Lint models/ssh_key.go
2016-11-27 12:13:43 +01:00
Thomas Boerger
93d527a0a4 Merge pull request #265 from Bwko/lint/access.go
Lint models/access.go
2016-11-27 12:12:56 +01:00
Thomas Boerger
8347a55cc2 Merge pull request #263 from Bwko/lint/user_email
Lint models/user_email.go
2016-11-27 12:12:02 +01:00
Thomas Boerger
bc59b8abc9 Merge pull request #273 from typeless/master
modules/process: add ExecDirEnv (next to ExecDir)
2016-11-27 12:11:04 +01:00
Mura Li
9aaf2a6d9a modules/process: add ExecDirEnv (next to ExecDir)
Add a sibling to ExecDir which is capable of specifying environment variables,
so that we can invoke `git` with GIT_INDEX_FILE, GIT_DIR, etc..

For #258
2016-11-27 18:53:57 +08:00
Andrey Nering
3ac72255fa Merge pull request #272 from andreynering/gitea/location-cherrypick-a3ea4b8
Update locales and add Swedish
2016-11-27 08:49:26 -02:00
Andrey Nering
c664ffd1db Merge pull request #270 from andreynering/gitea/http-headers-download
Fix HTTP headers for issue attachment download
2016-11-27 08:48:26 -02:00
Lunny Xiao
94da472717 Golint fixed for modules/setting (#262)
* golint fixed for modules/setting

* typo fixed and renamed UNIXSOCKET to UnixSocket
2016-11-27 18:14:25 +08:00
Lunny Xiao
5b998a6680 golint fixed for modules/auth 2016-11-27 14:03:59 +08:00
Unknwon
4cb21115dc Update locales and add Swedish
Signed-off-by: Andrey Nering <andrey.nering@gmail.com>
2016-11-26 14:22:55 -02:00
Andrey Nering
d647d02c2f Fix Chrome not liking commas 2016-11-26 11:26:03 -02:00
Andrey Nering
638dd24cec Fix HTTP headers for issue attachment download
- Download filename was wrong for files other than images. Example: It was `download` instead of `file.pdf`
- PDF was downloading instead of showing on browser
2016-11-26 10:13:25 -02:00
Lunny Xiao
3228544c31 golint fixed for modules/log 2016-11-26 19:53:29 +08:00
Bwko
0b9cf10340 Lint models/org.go & models.go 2016-11-26 11:37:50 +01:00
Bwko
7bf7042013 Lint models/repo_mirror.go 2016-11-26 11:23:55 +01:00
Bwko
ce8c9ef580 Lint models/repo_branch.go 2016-11-26 11:20:37 +01:00
Bwko
6cde041080 Lint models/ssh_key.go 2016-11-26 01:36:03 +01:00
Bwko
2bb1601d7c Lint models/access.go 2016-11-26 01:07:57 +01:00
Bwko
066f515a47 Lint models/user_email.go 2016-11-26 01:03:06 +01:00
Thomas Boerger
0a76d260fa Merge pull request #260 from tboerger/drone-latest
Dropped latest publishing from drone
2016-11-25 17:13:55 +01:00
Thomas Boerger
65549863bc Dropped latest publishing from drone 2016-11-25 13:07:19 +01:00
Thomas Boerger
574e49c854 Merge pull request #241 from Bwko/lint/admin.go
Lint models/admin.go
2016-11-25 12:55:24 +01:00
Thomas Boerger
21b7d30174 Merge pull request #245 from Bwko/lint/update&slack
Lint models/update.go, release.go & webhook_slack.go
2016-11-25 12:55:14 +01:00
Thomas Boerger
e9c6053b86 Merge pull request #246 from Bwko/fix/typo
Fix typos
2016-11-25 12:54:57 +01:00
Thomas Boerger
177a4c7385 Merge pull request #259 from tboerger/drone-fixes
Fixed s3 publishing within drone
2016-11-25 11:48:17 +01:00
Thomas Boerger
0accc935a3 Fixed s3 publishing within drone 2016-11-25 10:53:48 +01:00
Thomas Boerger
5d4333eb0d Merge pull request #240 from go-gitea/drone-additions
Additions to the Drone CI integration
2016-11-25 10:25:01 +01:00
Thomas Boerger
32f8a38f6c Merge pull request #254 from lunny/lunny/golint_modules_context
Golint fixed for modules/context
2016-11-25 10:11:52 +01:00
Thomas Boerger
3ae7955d15 Disable broken docker build for now 2016-11-25 10:11:49 +01:00
Thomas Boerger
755ed84740 Be more explicit and dropped matrix builds from drone 2016-11-25 10:11:49 +01:00
Thomas Boerger
5b17661c5d Updated badges for drone and similar to lgtm 2016-11-25 10:11:49 +01:00
Thomas Boerger
3e6f363471 Merge pull request #256 from lunny/lunny/golint_modules_avatar
Golint fixed for modules/avatar
2016-11-25 10:11:44 +01:00
Thomas Boerger
2255a9af6a Merge pull request #255 from lunny/lunny/golint_modules_cron
Golint fixed for modules/cron
2016-11-25 10:11:36 +01:00
Thomas Boerger
26ae2ff86d Merge pull request #252 from lunny/lunny/golint_fixed_modules_httplib
Golint fixed for modules/httplib
2016-11-25 10:08:49 +01:00
Thomas Boerger
d39266228c Merge pull request #251 from lunny/lunny/golint_modules_template
Golint fixed for modules/template
2016-11-25 10:08:37 +01:00
Thomas Boerger
7c5de1e393 Merge pull request #250 from lunny/lunny/golint_modules_markdown
Golint fixed for modules/markdown
2016-11-25 10:08:23 +01:00
Thomas Boerger
a321ffbcce Merge pull request #249 from lunny/lunny/golint_modules_mailer
Golint fixed for modules/mailer
2016-11-25 10:07:52 +01:00
Lunny Xiao
3c87c57d96 golint fixed for modules/avatar 2016-11-25 16:37:04 +08:00
Lunny Xiao
b47051e59b golint fixed for modules/cron 2016-11-25 16:19:24 +08:00
Thomas Boerger
900a21008c Added errcheck make task (#242) 2016-11-25 16:12:06 +08:00
Bwko
c0ca6644ad Lint/issue &mail (#243)
* Lint models/release.go

* Lint models/ issue_label, issue_mail & mail.go
2016-11-25 16:11:12 +08:00
Bwko
081c2a9395 Lint models/token.go (#244) 2016-11-25 16:03:52 +08:00
Lunny Xiao
76604d8f90 fixed test build error 2016-11-25 16:02:10 +08:00
Bwko
33a2ac3830 Lint models/update.go & webhook_slack.go 2016-11-25 07:55:08 +01:00
Lunny Xiao
faabc76fd6 Golint fixed for modules/context 2016-11-25 14:53:59 +08:00
Lunny Xiao
bd5ea3e222 Golint fixed for modules/httplib 2016-11-25 14:32:09 +08:00
Lunny Xiao
229ec927b9 Golint fixed for modules/template 2016-11-25 14:23:48 +08:00
Lunny Xiao
304bbd3f25 golint fixed for modules/markdown 2016-11-25 09:58:05 +08:00
Lunny Xiao
2e565bc1c4 Golint fixed for modules/mailer 2016-11-25 09:44:04 +08:00
Andrey Nering
6a28909f40 CONTRIBUTING.md: link to "Faster reviews" document (#229)
* CONTRIBUTING.md: link to "Faster reviews" document

* CONTRIBUTING.md: small fixes
2016-11-25 09:25:34 +08:00
Bwko
d8e11a8eaa Lint models/admin.go 2016-11-24 23:42:07 +01:00
Bwko
ece19f4a5e Lint models/release.go 2016-11-24 22:02:54 +01:00
Thomas Boerger
21e8deed89 Merge pull request #96 from metalmatze/feature/drone-config
Create a first draft for .drone.yml
2016-11-24 21:36:47 +01:00
Lunny Xiao
450969c158 test database is connect OK after db config initialized (#239) 2016-11-24 22:30:36 +08:00
Thomas Boerger
ba2e75a0ab Merge pull request #238 from go-gitea/make-install
Really use go install on make install
2016-11-24 15:29:17 +01:00
Thomas Boerger
fd090dc29b Added matrix drone builds 2016-11-24 14:48:40 +01:00
Matthias Loibl
4c03974326 Create a first draft for .drone.yml 2016-11-24 14:47:36 +01:00
Thomas Boerger
cb0b91cdc9 Dropped travis config 2016-11-24 14:41:59 +01:00
Thomas Boerger
fd13b71fb2 Added drone instead of travis detection to makefile 2016-11-24 14:41:30 +01:00
Thomas Boerger
cd7e661870 Added dummy tasks for mysql and pgsql tests 2016-11-24 14:40:56 +01:00
Thomas Boerger
cc8c57458f Really use go install on make install 2016-11-24 14:38:37 +01:00
Thomas Boerger
b6b616b336 Merge pull request #228 from Bwko/feature/short-hash-download
Added short-hash support to downloads
2016-11-24 13:38:14 +01:00
Thomas Boerger
289f819f78 Merge pull request #237 from strk/login_source-lint
Lint models/login_source.go
2016-11-24 13:37:01 +01:00
Sandro Santilli
1c3044b873 Lint models/login_source.go 2016-11-24 12:34:38 +01:00
Bwko
ff0d1bd602 Added short-hash support to downloads 2016-11-24 11:45:16 +01:00
Thomas Boerger
2ccdcda072 Merge pull request #235 from lunny/lunny/golint_modules_user
golint fixed for modules/user
2016-11-24 11:33:47 +01:00
Thomas Boerger
0a66c2a2d9 Merge pull request #234 from strk/issue-lint
Lint issue.go
2016-11-24 11:30:39 +01:00
Thomas Boerger
e512411863 Merge pull request #233 from strk/git_diff-lint
Lint git_diff.go
2016-11-24 11:29:51 +01:00
Thomas Boerger
03b6880089 Merge pull request #232 from strk/error-lint
Lint error.go
2016-11-24 11:29:15 +01:00
Thomas Boerger
8ba0ac976f Merge pull request #231 from lunny/lunny/golint_modules_base
golint fixed for modules/base
2016-11-24 11:28:31 +01:00
Thomas Boerger
1cfbfb3812 Merge pull request #212 from strk/action-lint
Lint action.go
2016-11-24 11:17:04 +01:00
Thomas Boerger
f0cfb1cb03 Merge pull request #192 from strk/make-default-target
Have the default 'all' rule just build
2016-11-24 11:13:35 +01:00
Thomas Boerger
0581210a76 Merge pull request #176 from strk/manager-lint
Lint and document manager api
2016-11-24 11:10:34 +01:00
Lunny Xiao
46ecb0a14d golint fixed for modules/user 2016-11-24 17:37:11 +08:00
Sandro Santilli
8aa960f129 Actually document the missing bits 2016-11-24 09:41:11 +01:00
Sandro Santilli
3fba29c571 Expand documentations 2016-11-24 09:30:08 +01:00
Sandro Santilli
0a61d54a9c Expand documentation a bit more 2016-11-24 09:20:28 +01:00
Sandro Santilli
dd9d0f3732 Lint action.go 2016-11-24 09:03:29 +01:00
Sandro Santilli
170f2e98cc Lint error.go
This was done semi-programmatically, not really documenting anything
2016-11-24 09:03:17 +01:00
Sandro Santilli
6e644726d0 Lint git_diff.go
Semi-automatic linting (don't really document things)
2016-11-24 09:02:58 +01:00
Sandro Santilli
4dd1eb57bd Lint issue.go 2016-11-24 09:02:44 +01:00
Sandro Santilli
5301a5db3a Have the deault 'all' rule just build
Clean and test are saner being seperate targets
2016-11-24 09:02:32 +01:00
Sandro Santilli
ad3d6b7fff Lint and document manager api 2016-11-24 09:02:10 +01:00
Lunny Xiao
6ed7f269f1 Move init functions from routers/install to routers/init (#230)
* move init functions from routers/install to routers/init

* copyright typo
2016-11-24 15:40:16 +08:00
Lunny Xiao
fb3bb69ec6 golint fixed for modules/base 2016-11-24 15:17:44 +08:00
Lunny Xiao
3917ed45de golint fixed for routers (#208) 2016-11-24 15:04:31 +08:00
stroucki
3a3782bb7f Handle ssh key import better (#224)
* Handle user ssh key input better

ssh_key: when user submitted keys had a newline at the end, strings.Split
would have created a slice with an empty last element, and the key type
check would be incorrect. Perhaps a better way is to look for 'ssh-rsa' or
'ssh-dsa' at the beginning of the string, but this is simple.

* ssh_key: correct indentation
2016-11-24 08:52:55 +08:00
Lunny Xiao
cb1602840c golint fixed for routers/repo/branch.go (#206) 2016-11-22 16:32:00 +08:00
Sandro Santilli
c25063d834 Lint webhook.go, unexports simpleMarshalJSON (#198) 2016-11-22 14:42:52 +08:00
Bwko
2a449bd4b1 Fix typos 2016-11-21 20:08:21 +01:00
Lunny Xiao
b2cce12980 golint fixed for routers/repo/wiki.go (#203) 2016-11-21 18:03:42 +08:00
Lunny Xiao
f0df8e8dfa golint fixed for routers/repo/middlewares.go (#204) 2016-11-21 18:03:37 +08:00
Lunny Xiao
18dc4f1023 golint fixed for routers/repo/view.go (#205) 2016-11-21 18:03:29 +08:00
Thomas Boerger
1d9576d5ea Merge pull request #202 from lunny/lunny/golint_fixed_routers_admin
go lint fixed for routers/admin
2016-11-21 10:37:14 +01:00
Lunny Xiao
659bc2814c go lint fixed for routers/admin 2016-11-21 11:29:25 +08:00
Andrey Nering
bd13c81684 Merge pull request #196 from Bwko/fix/commit-view-panic
Fix panic when no user is signed in
2016-11-19 14:30:37 -02:00
Bwko
7b75d93f3d Fix for anonymous users to switch views 2016-11-19 16:53:34 +01:00
Bwko
fc3ed8a1de Fix panic when no user is signed in
See #188
2016-11-19 12:43:10 +01:00
Lunny Xiao
cf045b029c golint fixed for parts of routers root, dev, user and org dirs (#167)
* golint fixed for parts of routers root, dev and org dirs

* add user/auth.go golint fixed

* rename unnecessary exported to unexported and user dir golint fixed
2016-11-18 11:03:03 +08:00
Andrey Nering
91953ae9b4 Merge pull request #187 from strk/vendor
Add vendoring section
2016-11-17 17:35:48 -02:00
Sandro Santilli
39b3fcad1d Wrap vendor/ in backtics 2016-11-17 17:06:13 +01:00
Sandro Santilli
4faf9c213e Add vendoring section
Closes #178
2016-11-17 16:49:12 +01:00
Andrey Nering
d884312223 Merge pull request #100 from ethantkoenig/develop
API endpoints for stars
2016-11-17 07:15:15 -02:00
Ethan Koenig
0834e492c0 API endpoints for stars 2016-11-16 22:51:54 -05:00
Thibault Meyer
871c964ef7 Upgrade vendor "git" (#175) 2016-11-15 23:24:08 +08:00
Matthias Loibl
7596e41027 Merge pull request #171 from andreynering/gitea/editorconfig-crlf
.editorconfig: do not specify line ending
2016-11-15 12:06:41 +01:00
Thomas Boerger
56a8cf523b fix variable assigned and not used. (#173)
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-11-15 07:53:16 +01:00
Bo-Yi Wu
d9ffe99972 fix variable assigned and not used.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-11-15 14:16:27 +08:00
Kim "BKC" Carlbäcker
07a0753420 Merge pull request #169 from strk/allow-update-draft-releases
Allow updating draft releases while keeping them as draft
2016-11-14 21:48:21 +01:00
Andrey Nering
6cf66117e7 Merge pull request #170 from strk/wiki-lint
Fix lint errors in models/wiki (just add methods docs)
2016-11-14 17:34:16 -02:00
Andrey Nering
a285c07d5e .editorconfig: do not specify line ending
That is annoying on Windows, since the editor will change the file if
you just open it. Git will checking as LF anyway.
2016-11-14 15:48:44 -02:00
Sandro Santilli
cd339263d9 Allow updating draft releases while keeping them as draft
Closes #162
2016-11-14 18:02:21 +01:00
Sandro Santilli
592a4ec4d3 Fix lint errors in models/wiki (just add methods docs)
See #70
2016-11-14 18:01:46 +01:00
Andrey Nering
81f227eace Merge pull request #168 from appleboy/gofmt
fix gofmt error.
2016-11-14 15:00:02 -02:00
Bo-Yi Wu
5054020c1f fix gofmt error.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-11-15 00:03:37 +08:00
Bo-Yi Wu
904deb7d6a Fix broken link for Contributors Guide (#166)
* Fix broken link for Contributors Guide

* remove ./
2016-11-14 08:17:15 +01:00
Andrey Nering
739f07c98e Remember diff view style (#163) 2016-11-13 10:54:04 +08:00
Lunny Xiao
bd76e156bb fixed bug #151 finally (#164) 2016-11-12 22:52:19 +08:00
LefsFlare
3ef022b071 Fixes possible vulnerabilities with keyword hijacking (#20)
- Added public entries to reserved keywords list
- Rename variables
- Derped comment
2016-11-12 13:26:45 +01:00
Lunny Xiao
3dedc027ac Bug fixed for issues (#156) 2016-11-12 13:06:33 +01:00
Thibault Meyer
54e6ed3431 Upgrade vendor "git" (#161) 2016-11-12 12:09:25 +01:00
Lunny Xiao
b339858500 replace footer gogs to gitea (#157) 2016-11-12 09:32:43 +01:00
Lunny Xiao
0baaa7728a bug fixed caused by #153 (#154) 2016-11-12 09:30:46 +01:00
Lunny Xiao
30a37311f8 use in instead string join (#155) 2016-11-12 09:29:18 +01:00
Lunny Xiao
555d8b16cb fixed bug #151 caused Find should be Get (#153) 2016-11-12 00:01:09 +01:00
Matthias Loibl
900f233b3c Merge pull request #152 from lunny/lunny/optimization_in
optimization on database IN
2016-11-11 22:09:54 +01:00
Lunny Xiao
ade6d4a20f optimization on database IN 2016-11-12 01:31:37 +08:00
Lunny Xiao
9bf28a2799 bug fixed for 500 caused by get org users (#149) 2016-11-12 00:55:06 +08:00
Lunny Xiao
a8c6698de8 Fix error 500 on organization dashboard page (#150) 2016-11-12 00:40:21 +08:00
981 changed files with 312997 additions and 4721 deletions

View File

@@ -1,19 +1,5 @@
.git
.git/**
packager
packager/**
scripts
scripts/**
.github/
.github/**
config.codekit
.dockerignore
*.yml
*.md
.bra.toml
.editorconfig
.gitignore
Dockerfile*
vendor
vendor/**
gogs
*
!gitea
!docker
!public
!templates

128
.drone.yml Normal file
View File

@@ -0,0 +1,128 @@
workspace:
base: /srv/app
path: src/code.gitea.io/gitea
pipeline:
test:
image: webhippie/golang:edge
pull: true
environment:
CGO_ENABLED: 1
TAGS: sqlite bindata
GOPATH: /srv/app
commands:
- apk -U add openssh-client
- make clean
- make generate
- make vet
- make lint
- make test
- make build
when:
event: [ push, tag, pull_request ]
test-mysql:
image: webhippie/golang:edge
pull: true
environment:
CGO_ENABLED: 1
TAGS: sqlite bindata
GOPATH: /srv/app
commands:
- make test-mysql
when:
event: [ push ]
test-pgsql:
image: webhippie/golang:edge
pull: true
environment:
CGO_ENABLED: 1
TAGS: sqlite bindata
GOPATH: /srv/app
commands:
- make test-pgsql
when:
event: [ push ]
updater:
image: karalabe/xgo-latest:latest
pull: true
environment:
CGO_ENABLED: 1
TAGS: sqlite bindata
GOPATH: /srv/app
commands:
- make release
when:
event: [ push, tag ]
branch: [ master, refs/tags/* ]
coverage:
image: plugins/coverage
server: https://coverage.gitea.io
when:
event: [ push, tag, pull_request ]
docker:
image: plugins/docker
repo: gitea/gitea
tags: [ '${TAG}' ]
when:
event: [ tag ]
branch: [ refs/tags/* ]
docker:
image: plugins/docker
repo: gitea/gitea
tags: [ 'latest' ]
when:
event: [ push ]
branch: [ master ]
release:
image: plugins/s3
path_style: true
strip_prefix: dist/release/
source: dist/release/*
target: /gitea/master
when:
event: [ push ]
branch: [ master ]
release:
image: plugins/s3
path_style: true
strip_prefix: dist/release/
source: dist/release/*
target: /gitea/$$TAG
when:
event: [ tag ]
branch: [ refs/tags/* ]
github:
image: plugins/github-release
files:
- dist/release/*
when:
event: [ tag ]
branch: [ refs/tags/* ]
gitter:
image: plugins/gitter
services:
mysql:
image: mysql:5.7
environment:
- MYSQL_DATABASE=test
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
when:
event: [ push ]
pgsql:
image: postgres:9.5
environment:
- POSTGRES_DB=test
when:
event: [ push ]

1
.drone.yml.sig Normal file
View File

@@ -0,0 +1 @@
eyJhbGciOiJIUzI1NiJ9.d29ya3NwYWNlOgogIGJhc2U6IC9zcnYvYXBwCiAgcGF0aDogc3JjL2NvZGUuZ2l0ZWEuaW8vZ2l0ZWEKCnBpcGVsaW5lOgogIHRlc3Q6CiAgICBpbWFnZTogd2ViaGlwcGllL2dvbGFuZzplZGdlCiAgICBwdWxsOiB0cnVlCiAgICBlbnZpcm9ubWVudDoKICAgICAgQ0dPX0VOQUJMRUQ6IDEKICAgICAgVEFHUzogc3FsaXRlIGJpbmRhdGEKICAgICAgR09QQVRIOiAvc3J2L2FwcAogICAgY29tbWFuZHM6CiAgICAgIC0gYXBrIC1VIGFkZCBvcGVuc3NoLWNsaWVudAogICAgICAtIG1ha2UgY2xlYW4KICAgICAgLSBtYWtlIGdlbmVyYXRlCiAgICAgIC0gbWFrZSB2ZXQKICAgICAgLSBtYWtlIGxpbnQKICAgICAgLSBtYWtlIHRlc3QKICAgICAgLSBtYWtlIGJ1aWxkCiAgICB3aGVuOgogICAgICBldmVudDogWyBwdXNoLCB0YWcsIHB1bGxfcmVxdWVzdCBdCgogIHRlc3QtbXlzcWw6CiAgICBpbWFnZTogd2ViaGlwcGllL2dvbGFuZzplZGdlCiAgICBwdWxsOiB0cnVlCiAgICBlbnZpcm9ubWVudDoKICAgICAgQ0dPX0VOQUJMRUQ6IDEKICAgICAgVEFHUzogc3FsaXRlIGJpbmRhdGEKICAgICAgR09QQVRIOiAvc3J2L2FwcAogICAgY29tbWFuZHM6CiAgICAgIC0gbWFrZSB0ZXN0LW15c3FsCiAgICB3aGVuOgogICAgICBldmVudDogWyBwdXNoIF0KCiAgdGVzdC1wZ3NxbDoKICAgIGltYWdlOiB3ZWJoaXBwaWUvZ29sYW5nOmVkZ2UKICAgIHB1bGw6IHRydWUKICAgIGVudmlyb25tZW50OgogICAgICBDR09fRU5BQkxFRDogMQogICAgICBUQUdTOiBzcWxpdGUgYmluZGF0YQogICAgICBHT1BBVEg6IC9zcnYvYXBwCiAgICBjb21tYW5kczoKICAgICAgLSBtYWtlIHRlc3QtcGdzcWwKICAgIHdoZW46CiAgICAgIGV2ZW50OiBbIHB1c2ggXQoKICB1cGRhdGVyOgogICAgaW1hZ2U6IGthcmFsYWJlL3hnby1sYXRlc3Q6bGF0ZXN0CiAgICBwdWxsOiB0cnVlCiAgICBlbnZpcm9ubWVudDoKICAgICAgQ0dPX0VOQUJMRUQ6IDEKICAgICAgVEFHUzogc3FsaXRlIGJpbmRhdGEKICAgICAgR09QQVRIOiAvc3J2L2FwcAogICAgY29tbWFuZHM6CiAgICAgIC0gbWFrZSByZWxlYXNlCiAgICB3aGVuOgogICAgICBldmVudDogWyBwdXNoLCB0YWcgXQogICAgICBicmFuY2g6IFsgbWFzdGVyLCByZWZzL3RhZ3MvKiBdCgogIGNvdmVyYWdlOgogICAgaW1hZ2U6IHBsdWdpbnMvY292ZXJhZ2UKICAgIHNlcnZlcjogaHR0cHM6Ly9jb3ZlcmFnZS5naXRlYS5pbwogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgcHVzaCwgdGFnLCBwdWxsX3JlcXVlc3QgXQoKICBkb2NrZXI6CiAgICBpbWFnZTogcGx1Z2lucy9kb2NrZXIKICAgIHJlcG86IGdpdGVhL2dpdGVhCiAgICB0YWdzOiBbICcke1RBR30nIF0KICAgIHdoZW46CiAgICAgIGV2ZW50OiBbIHRhZyBdCiAgICAgIGJyYW5jaDogWyByZWZzL3RhZ3MvKiBdCgogIGRvY2tlcjoKICAgIGltYWdlOiBwbHVnaW5zL2RvY2tlcgogICAgcmVwbzogZ2l0ZWEvZ2l0ZWEKICAgIHRhZ3M6IFsgJ2xhdGVzdCcgXQogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgcHVzaCBdCiAgICAgIGJyYW5jaDogWyBtYXN0ZXIgXQoKICByZWxlYXNlOgogICAgaW1hZ2U6IHBsdWdpbnMvczMKICAgIHBhdGhfc3R5bGU6IHRydWUKICAgIHN0cmlwX3ByZWZpeDogZGlzdC9yZWxlYXNlLwogICAgc291cmNlOiBkaXN0L3JlbGVhc2UvKgogICAgdGFyZ2V0OiAvZ2l0ZWEvbWFzdGVyCiAgICB3aGVuOgogICAgICBldmVudDogWyBwdXNoIF0KICAgICAgYnJhbmNoOiBbIG1hc3RlciBdCgogIHJlbGVhc2U6CiAgICBpbWFnZTogcGx1Z2lucy9zMwogICAgcGF0aF9zdHlsZTogdHJ1ZQogICAgc3RyaXBfcHJlZml4OiBkaXN0L3JlbGVhc2UvCiAgICBzb3VyY2U6IGRpc3QvcmVsZWFzZS8qCiAgICB0YXJnZXQ6IC9naXRlYS8kJFRBRwogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgdGFnIF0KICAgICAgYnJhbmNoOiBbIHJlZnMvdGFncy8qIF0KCiAgZ2l0aHViOgogICAgaW1hZ2U6IHBsdWdpbnMvZ2l0aHViLXJlbGVhc2UKICAgIGZpbGVzOgogICAgICAtIGRpc3QvcmVsZWFzZS8qCiAgICB3aGVuOgogICAgICBldmVudDogWyB0YWcgXQogICAgICBicmFuY2g6IFsgcmVmcy90YWdzLyogXQoKICBnaXR0ZXI6CiAgICBpbWFnZTogcGx1Z2lucy9naXR0ZXIKCnNlcnZpY2VzOgogIG15c3FsOgogICAgaW1hZ2U6IG15c3FsOjUuNwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gTVlTUUxfREFUQUJBU0U9dGVzdAogICAgICAtIE1ZU1FMX0FMTE9XX0VNUFRZX1BBU1NXT1JEPXllcwogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgcHVzaCBdCgogIHBnc3FsOgogICAgaW1hZ2U6IHBvc3RncmVzOjkuNQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUE9TVEdSRVNfREI9dGVzdAogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgcHVzaCBdCg.O00lMwJDnAI1CFYbrs1bAmspX4wA5ufdye66vq5lcWw

View File

@@ -4,7 +4,6 @@ root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
@@ -12,17 +11,17 @@ trim_trailing_whitespace = true
indent_style = tab
indent_size = 8
[*.tmpl]
indent_style = tab
indent_size = 2
[Makefile]
[*.{tmpl,html}]
indent_style = tab
indent_size = 4
[*.{less,yml}]
indent_style = space
indent_size = 2
indent_size = 4
[*.js]
indent_style = space
indent_size = 4
[Makefile]
indent_style = tab

11
.gitattributes vendored
View File

@@ -1,11 +0,0 @@
public/conf/gitignore/* linguist-vendored
public/conf/license/* linguist-vendored
public/assets/* linguist-vendored
public/plugins/* linguist-vendored
public/plugins/* linguist-vendored
public/css/themes/* linguist-vendored
public/css/github.min.css linguist-vendored
public/css/semantic-2.2.1.min.css linguist-vendored
public/js/libs/* linguist-vendored
public/js/jquery-1.11.3.min.js linguist-vendored
public/js/semantic-2.2.1.min.js linguist-vendored

View File

@@ -1,24 +0,0 @@
1. Please speak English
2. Please ask questions or config/deploy problems
on our gitter channel: https://gitter.im/go-gitea/gitea
Here are bugs and feature requests only.
3. Please take a moment to search that an issue doesn't already exist.
4. Please give all relevant information below for bug reports; incomplete
details considered invalid report.
**You MUST delete above content including this line before posting;
too lazy to take this action considered invalid report.**
- Gitea version (or commit ref):
- Git version:
- Operating system:
- Database (use `[x]`):
- [ ] PostgreSQL
- [ ] MySQL
- [ ] SQLite
- Log gist:
## Description
...

View File

@@ -1,10 +0,0 @@
Please check the following:
1. Make sure you are targeting the `master` branch.
2. Read contributing guidelines:
https://github.com/go-gitea/gitea/blob/master/CONTRIBUTING.md
3. Describe what your pull request does and which issue
you're targeting (if any)
**You MUST delete above content including this line before posting;
too lazy to take this action considered invalid pull request.**

19
.github/issue_template.md vendored Normal file
View File

@@ -0,0 +1,19 @@
1. Please speak English, this is the language everybody of us can speak and write.
2. Please ask questions or config/deploy problems on our Gitter channel: https://gitter.im/go-gitea/gitea
3. Please take a moment to search that an issue doesn't already exist.
4. Please give all relevant information below for bug reports, incomplete details will be handled as an invalid report.
**You MUST delete the content above including this line before posting, otherwise your pull request will be invalid.**
- Gitea version (or commit ref):
- Git version:
- Operating system:
- Database (use `[x]`):
- [ ] PostgreSQL
- [ ] MySQL
- [ ] SQLite
- Log gist:
## Description
...

7
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,7 @@
Please check the following:
1. Make sure you are targeting the `master` branch, pull requests on release branches are only allowed for bug fixes.
2. Read contributing guidelines: https://github.com/go-gitea/gitea/blob/master/CONTRIBUTING.md
3. Describe what your pull request does and which issue you're targeting (if any)
**You MUST delete the content above including this line before posting, otherwise your pull request will be invalid.**

3
.gitignore vendored
View File

@@ -28,6 +28,9 @@ _testmain.go
coverage.out
/modules/public/bindata.go
/modules/templates/bindata.go
*.db
*.log

View File

@@ -1,2 +0,0 @@
Unknwon <u@gogs.io> <joe2010xtmf@163.com>
Unknwon <u@gogs.io> 无闻 <u@gogs.io>

View File

@@ -1,36 +0,0 @@
language: go
go_import_path: code.gitea.io/gitea
go:
- 1.6
- 1.7
env:
TAGS: cert sqlite pam miniwinsvc
before_install:
- sudo apt-get update -qq
- sudo apt-get install -y libpam-dev
script:
- make clean
- make vet
# - make lint
- make test
- make build
after_success:
- bash <(curl -s https://codecov.io/bash)
notifications:
webhooks:
on_success: change
on_failure: always
on_start: never
urls:
- https://webhooks.gitter.im/e/ee6b822f3cf54c98e70c
- https://webhooks.gitter.im/e/87428658ef177ce8a7e4
- https://webhooks.gitter.im/e/a1d2b69804dfda72187e

View File

@@ -2,161 +2,85 @@
## Introduction
This document explains how to contribute changes to the Gitea
project. It assumes you have followed the [installation
instructions](https://github.com/go-gitea/docs/tree/master/en-US/installation)
Sensitive security-related issues should be reported to
[security@gitea.io](mailto:security@gitea.io).
This document explains how to contribute changes to the Gitea project. It assumes you have followed the [installation instructions](https://github.com/go-gitea/docs/tree/master/en-US/installation). Sensitive security-related issues should be reported to [security@gitea.io](mailto:security@gitea.io).
## Bug reports
Please search the issues on the issue tracker with a variety of keywords
to ensure your bug is not already reported.
Please search the issues on the issue tracker with a variety of keywords to ensure your bug is not already reported.
If unique, [open an issue](https://github.com/go-gitea/gitea/issues/new)
and answer the questions so we can understand and reproduce the
problematic behavior.
If unique, [open an issue](https://github.com/go-gitea/gitea/issues/new) and answer the questions so we can understand and reproduce the problematic behavior.
The burden is on you to convince us that it is actually a bug
in Gitea. This is easiest to do when you write clear, concise
instructions so we can reproduce the behavior (even if it seems
obvious). The more detailed and specific you are, the faster
we will be able to help you. Check out [How to Report Bugs
Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html).
The burden is on you to convince us that it is actually a bug in Gitea. This is easiest to do when you write clear, concise instructions so we can reproduce the behavior (even if it seems obvious). The more detailed and specific you are, the faster we will be able to help you. Check out [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html).
Please be kind, remember that Gitea comes at no cost to you, and you're
getting free help.
Please be kind, remember that Gitea comes at no cost to you, and you're getting free help.
## Discuss your design
The project welcomes submissions but please let everyone know what
you're working on if you want to change or add something to the Gitea
repositories.
The project welcomes submissions but please let everyone know what you're working on if you want to change or add something to the Gitea repositories.
Before starting to write something new for the Gitea project, please
[file an issue](https://github.com/go-gitea/gitea/issues/new).
Significant changes must go through the [change proposal
process](https://github.com/go-gitea/proposals) before they can be
accepted.
Before starting to write something new for the Gitea project, please [file an issue](https://github.com/go-gitea/gitea/issues/new). Significant changes must go through the [change proposal process](https://github.com/go-gitea/proposals) before they can be accepted.
This process gives everyone a chance to validate the design, helps
prevent duplication of effort, and ensures that the idea fits inside
the goals for the project and tools. It also checks that the design is
sound before code is written; the code review tool is not the place for
high-level discussions.
This process gives everyone a chance to validate the design, helps prevent duplication of effort, and ensures that the idea fits inside the goals for the project and tools. It also checks that the design is sound before code is written; the code review tool is not the place for high-level discussions.
## Testing redux
Before sending code out for review, run all the tests for the whole
tree to make sure the changes don't break other usage and keep the
compatibility on upgrade:
After running for a while, the command should print
```
ALL TESTS PASSED
```
Before sending code out for review, run all the tests for the whole tree to make sure the changes don't break other usage and keep the compatibility on upgrade. To make sure you are running the test suite exactly like we do you should install the CLI for [Drone CI](https://github.com/drone/drone), as we are using the server for continous testing, following [these instructions](http://readme.drone.io/0.5/install/cli/). After that you can simply call `drone exec` within your working directory and it will try to run the test suite locally.
## Code review
Changes to Gitea must be reviewed before they are accepted, no matter
who makes the change even if an owners or a maintainer. We use github's
pull request workflow to do that and use [lgtm](http://lgtm.co) to ensure
every PR is reviewed by at least 2 maintainers.
Changes to Gitea must be reviewed before they are accepted, no matter who makes the change even if it is an owner or a maintainer. We use GitHub's pull request workflow to do that and we also use [LGTM](http://lgtm.co) to ensure every PR is reviewed by at least 2 maintainers.
Please try to make your pull request easy to review for us. Please read the "[How to get faster PR reviews](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/faster_reviews.md)" guide, it has lots of useful tips for any project you may want to contribute. Some of the key points:
* Make small pull requests. The smaller, the faster to review and the more likely it will be merged soon.
* Don't make changes unrelated to your PR. Maybe there are typos on some comments, maybe refactoring would be welcome on a function... but if that is not related to your PR, please make *another* PR for that.
* Split big pull requests in multiple small ones. An incremental change will be faster to review than a huge PR.
## Sign your work
The sign-off is a simple line at the end of the explanation for the
patch. Your signature certifies that you wrote the patch or otherwise
have the right to pass it on as an open-source patch. The rules are
pretty simple: If you can certify [DCO](DCO), then you just add a line
to every git commit message:
The sign-off is a simple line at the end of the explanation for the patch. Your signature certifies that you wrote the patch or otherwise have the right to pass it on as an open-source patch. The rules are pretty simple: If you can certify [DCO](DCO), then you just add a line to every git commit message:
```
Signed-off-by: Joe Smith <joe.smith@email.com>
```
Please use your real name, we really dislike pseudonyms or anonymous
contributions. We are in the opensource world without secrets. If you
set your `user.name` and `user.email` git configs, you can sign your
commit automatically with `git commit -s`.
## Contributors
Everyone who sent a PR to Gitea that gets accepted will
be as a contributor. Please send a PR to add your name to
[CONTRIBUTORS](CONTRIBUTORS). For the format, see the
[CONTRIBUTORS](CONTRIBUTORS).
Please use your real name, we really dislike pseudonyms or anonymous contributions. We are in the opensource world without secrets. If you set your `user.name` and `user.email` git configs, you can sign your commit automatically with `git commit -s`.
## Maintainers
To make sure every PR have been checked, we make a team maintainers. Any
PR MUST be reviewed and by at least two maintainers before it can
get merged. Maintainers should be a contributor of gitea(or gogs) and
contributed at least 4 accepted PRs. And a contributor should apply as a
maintainer in [gitter Gitea develop](https://gitter.im/go-gitea/develop).
And the owners or the team maintainer could invite the contributor. A
maintainer should spend some time on code reviews. If some maintainer
have no time to do that, he should apply to leave maintainers team and
we will give him an honor to be as a member of advisor team. Of course,
if an advisor have time to code view, welcome it back to maintainers team.
If some one have no time to code view and forget to leave the maintainers,
the owners have the power to move him from maintainers team to advisors
team.
To make sure every PR is checked, we got team maintainers. Every PR **MUST** be reviewed by at least two maintainers (or owners) before it can get merged. A maintainer should be a contributor of Gitea (or Gogs) and contributed at least 4 accepted PRs. A contributor should apply as a maintainer in the [Gitter develop channel](https://gitter.im/go-gitea/develop). The owners or the team maintainers may invite the contributor. A maintainer should spend some time on code reviews. If a maintainer has no time to do that, they should apply to leave the maintainers team and we will give them the honor of being a member of the advisors team. Of course, if an advisor has time to code review, we will gladly welcome them back to maintainers team. If someone has no time to code review and forgets to leave the maintainers team, the owners have the power to move him from maintainers team to advisors team.
## Owners
Since Gitea is a pure community organization without any company
support, to keep the development healthly We will elect the owners every
year. Every time we will elect three owners. All the contributers could
vote for three owners, one is the main owner, the other two are assistant
owners. When the new owners have been elected, the old owners MUST move
the power to the new owners. If some owner don't obey these rules,
the other owners are allowed to revoke his owner status.
Since Gitea is a pure community organization without any company support, to keep the development healthy we will elect the owners every year. Every time we will elect three owners. All the contributors may vote up to three people, one of which is the main owner, and the others are assistant owners. When the new owners have been elected, the old owners MUST move the power to the new ones. If an owner don't obey these rules, the others are allowed to revoke his owner status.
After the election, the new owners should say he agrees with these
rules on the [CONTRIBUTING](CONTRIBUTING.md) on the [Gitter Gitea
Channel](https://gitter.im/go-gitea/gitea). Below is the word to speak
After the election, the new owners should say they agree with these rules on the [CONTRIBUTING](CONTRIBUTING.md) on the [Gitter main channel](https://gitter.im/go-gitea/gitea). Below are the words to speak:
```
I'm glad to be an owner of Gitea,
I agree with [CONTRIBUTING](CONTRIBUTING.md).
I will spend part of my time on gitea
and lead the development of gitea.
I'm glad to be an owner of Gitea, I agree with [CONTRIBUTING](CONTRIBUTING.md). I will spend part of my time on Gitea and lead the development of Gitea.
```
For a honor to the owners, this document will add the history owners
below:
To honor the past owners, here's the history of the owners and the time they served:
2016-11-04 ~ 2017-12-31
- lunny <xiaolunwen@gmail.com>
- tboerger <thomas@webhippie.de>
- bkcsoft <kim.carlbacker@gmail.com>
* 2016-11-04 ~ 2017-12-31
* [Lunny Xiao](https://github.com/lunny) <xiaolunwen@gmail.com>
* [Thomas Boerger](https://github.com/tboerger) <thomas@webhippie.de>
* [Kim Carlbäcker](https://github.com/bkcsoft) <kim.carlbacker@gmail.com>
## Versions
Gitea has one master as a tip branch and have many version branch
such as v0.9. v0.9 is a release branch and we will tag v0.9.0 both for
binary download. If v0.9.0 have some bugs, we will accept PR on v0.9
and publish v0.9.1 and merge bug PR to master.
Gitea has the `master` branch as a tip branch and has version branches such as `v0.9`. `v0.9` is a release branch and we will tag `v0.9.0` for binary download. If `v0.9.0` has bugs, we will accept pull requests on the `v0.9` branch and publish a `v0.9.1` tag, after bringing the bug fix also to the master branch.
Branch master is a tip version, so if you wish a production usage,
please download the latest release tag version. All the branch will be
protected via github, All the PRs to all the branches should be review
by two maintainers and pass the automatic tests.
Since the `master` branch is a tip version, if you wish to use Gitea in production, please download the latest release tag version. All the branches will be protected via GitHub, all the PRs to every branch must be reviewed by two maintainers and must pass the automatic tests.
## Copyright
Code that you contribute should use the standard copyright header:
```
// Copyright 2016 - 2017 The Gitea Authors. All rights reserved.
// Copyright 2016 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
```
Files in the repository are copyright the year they are added and the
year they are last changed. If the copyright author is changed, just
copy the head below the old one.
Files in the repository contain copyright from the year they are added to the year they are last changed. If the copyright author is changed, just paste the header below the old one.

View File

@@ -1,22 +1,44 @@
FROM alpine:3.3
MAINTAINER jp@roemer.im
FROM alpine:3.4
MAINTAINER Thomas Boerger <thomas@webhippie.de>
# Install system utils & Gogs runtime dependencies
ADD https://github.com/tianon/gosu/releases/download/1.9/gosu-amd64 /usr/sbin/gosu
RUN chmod +x /usr/sbin/gosu \
&& apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat tzdata
ENV GITEA_CUSTOM /data/gogs
COPY . /app/gogs/
WORKDIR /app/gogs/
RUN ./docker/build.sh
# Configure LibC Name Service
COPY docker/nsswitch.conf /etc/nsswitch.conf
# Configure Docker Container
VOLUME ["/data"]
EXPOSE 22 3000
ENTRYPOINT ["docker/start.sh"]
CMD ["/bin/s6-svscan", "/app/gogs/docker/s6/"]
RUN apk update && \
apk add \
su-exec \
ca-certificates \
sqlite \
bash \
git \
linux-pam \
s6 \
curl \
openssh \
tzdata && \
rm -rf \
/var/cache/apk/* && \
addgroup \
-S -g 1000 \
git && \
adduser \
-S -H -D \
-h /data/git \
-s /bin/bash \
-u 1000 \
-G git \
git
ENV USER git
ENV GITEA_CUSTOM /data/gitea
ENV GODEBUG=netdns=go
VOLUME ["/data"]
ENTRYPOINT ["/usr/bin/entrypoint"]
CMD ["/bin/s6-svscan", "/etc/s6"]
COPY docker /
COPY public /app/gitea/public
COPY templates /app/gitea/templates
COPY gitea /app/gitea/gitea

View File

@@ -1,25 +1,44 @@
FROM hypriot/rpi-alpine-scratch:v3.2
MAINTAINER jp@roemer.im, raxetul@gmail.com
FROM hypriot/rpi-alpine-scratch:v3.4
MAINTAINER Thomas Boerger <thomas@webhippie.de>
# Install system utils & Gogs runtime dependencies
ADD https://github.com/tianon/gosu/releases/download/1.9/gosu-armhf /usr/sbin/gosu
RUN chmod +x /usr/sbin/gosu \
&& echo "http://dl-4.alpinelinux.org/alpine/v3.3/main/" | tee /etc/apk/repositories \
&& echo "http://dl-4.alpinelinux.org/alpine/v3.3/community/" | tee -a /etc/apk/repositories \
&& apk -U --no-progress upgrade && rm -f /var/cache/apk/APKINDEX.* \
&& apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat tzdata
ENV GITEA_CUSTOM /data/gogs
COPY . /app/gogs/
WORKDIR /app/gogs/
RUN ./docker/build.sh
# Configure LibC Name Service
COPY docker/nsswitch.conf /etc/nsswitch.conf
# Configure Docker Container
VOLUME ["/data"]
EXPOSE 22 3000
ENTRYPOINT ["docker/start.sh"]
CMD ["/bin/s6-svscan", "/app/gogs/docker/s6/"]
RUN apk update && \
apk add \
su-exec \
ca-certificates \
sqlite \
bash \
git \
linux-pam \
s6 \
curl \
openssh \
tzdata && \
rm -rf \
/var/cache/apk/* && \
addgroup \
-S -g 1000 \
git && \
adduser \
-S -H -D \
-h /data/git \
-s /bin/bash \
-u 1000 \
-G git \
git
ENV USER git
ENV GITEA_CUSTOM /data/gitea
ENV GODEBUG=netdns=go
VOLUME ["/data"]
ENTRYPOINT ["/usr/bin/entrypoint"]
CMD ["/bin/s6-svscan", "/etc/s6"]
COPY docker /
COPY public /app/gitea/public
COPY templates /app/gitea/templates
COPY gitea /app/gitea/gitea

View File

@@ -1,4 +1,6 @@
Andrey Nering <nobody@nobody.tld> (@andreynering)
Alexey Makhov <amakhov@avito.ru> (@makhov)
Andrey Nering <andrey.nering@gmail.com> (@andreynering)
Kees de Vries <bouwko@gmail.com> (@Bwko)
Kim Carlbäcker <kim.carlbacker@gmail.com> (@bkcsoft)
LefsFlare <nobody@nobody.tld> (@LefsFlarey)
Lunny Xiao <xiaolunwen@gmail.com> (@lunny)
@@ -6,5 +8,5 @@ Matthias Loibl <mail@matthiasloibl.com> (@metalmatze)
Rachid Zarouali <nobody@nobody.tld> (@xinity)
Rémy Boulanouar <admin@dblk.org> (@DblK)
Sandro Santilli <strk@kbt.io> (@strk)
Thibault Meyer <nobody@nobody.tld> (@0xbaadf00d)
Thibault Meyer <meyer.thibault@gmail.com> (@0xbaadf00d)
Thomas Boerger <thomas@webhippie.de> (@tboerger)

View File

@@ -1,6 +1,4 @@
DIST := dist
BIN := bin
EXECUTABLE := gitea
IMPORT := code.gitea.io/gitea
@@ -16,32 +14,27 @@ LDFLAGS += -X "code.gitea.io/gitea/modules/setting.BuildGitHash=$(SHA)"
TARGETS ?= linux/*,darwin/*,windows/*
PACKAGES ?= $(shell go list ./... | grep -v /vendor/)
SOURCES ?= $(shell find . -name "*.go" -type f)
TAGS ?=
ifneq ($(TRAVIS_TAG),)
VERSION ?= $(TRAVIS_TAG)
ifneq ($(DRONE_TAG),)
VERSION ?= $(DRONE_TAG)
else
ifneq ($(TRAVIS_BRANCH),)
VERSION ?= $(TRAVIS_BRANCH)
ifneq ($(DRONE_BRANCH),)
VERSION ?= $(DRONE_BRANCH)
else
VERSION ?= master
endif
endif
.PHONY: all
all: clean test build
all: build
.PHONY: clean
clean:
go clean -i ./...
rm -rf $(BIN) $(DIST)
.PHONY: deps
deps:
@which go-bindata > /dev/null; if [ $$? -ne 0 ]; then \
go get -u github.com/jteeuwen/go-bindata/...; \
fi
rm -rf $(EXECUTABLE) $(DIST)
.PHONY: fmt
fmt:
@@ -51,6 +44,20 @@ fmt:
vet:
go vet $(PACKAGES)
.PHONY: generate
generate:
@which go-bindata > /dev/null; if [ $$? -ne 0 ]; then \
go get -u github.com/jteeuwen/go-bindata/...; \
fi
go generate $(PACKAGES)
.PHONY: errcheck
errcheck:
@which errcheck > /dev/null; if [ $$? -ne 0 ]; then \
go get -u github.com/kisielk/errcheck; \
fi
errcheck $(PACKAGES)
.PHONY: lint
lint:
@which golint > /dev/null; if [ $$? -ne 0 ]; then \
@@ -62,60 +69,64 @@ lint:
test:
for PKG in $(PACKAGES); do go test -cover -coverprofile $$GOPATH/src/$$PKG/coverage.out $$PKG || exit 1; done;
.PHONY: test-mysql
test-mysql:
@echo "Not integrated yet!"
.PHONY: test-pgsql
test-pgsql:
@echo "Not integrated yet!"
.PHONY: check
check: test
.PHONY: install
install: $(BIN)/$(EXECUTABLE)
cp $< $(GOPATH)/bin/
install: $(wildcard *.go)
go install -v -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)'
.PHONY: build
build: $(BIN)/$(EXECUTABLE)
build: $(EXECUTABLE)
$(BIN)/$(EXECUTABLE): $(wildcard *.go)
$(EXECUTABLE): $(SOURCES)
go build -v -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
.PHONY: release
release: release-build release-copy release-check
release: release-dirs release-build release-copy release-check
.PHONY: release-dirs
release-dirs:
mkdir -p $(DIST)/binaries $(DIST)/release
.PHONY: release-build
release-build:
@which xgo > /dev/null; if [ $$? -ne 0 ]; then \
go get -u github.com/karalabe/xgo; \
fi
xgo -dest $(BIN) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -targets '$(TARGETS)' -out $(EXECUTABLE)-$(VERSION) $(IMPORT)
xgo -dest $(DIST)/binaries -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -targets '$(TARGETS)' -out $(EXECUTABLE)-$(VERSION) $(IMPORT)
ifeq ($(CI),drone)
mv /build/* $(DIST)/binaries
endif
.PHONY: release-copy
release-copy:
mkdir -p $(DIST)/release
$(foreach file,$(wildcard $(BIN)/$(EXECUTABLE)-*),cp $(file) $(DIST)/release/$(notdir $(file));)
$(foreach file,$(wildcard $(DIST)/binaries/$(EXECUTABLE)-*),cp $(file) $(DIST)/release/$(notdir $(file));)
.PHONY: release-check
release-check:
cd $(DIST)/release; $(foreach file,$(wildcard $(DIST)/release/$(EXECUTABLE)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;)
.PHONY: latest
latest: release-build latest-copy latest-check
.PHONY: latest-copy
latest-copy:
mkdir -p $(DIST)/latest
$(foreach file,$(wildcard $(BIN)/$(EXECUTABLE)-*),cp $(file) $(DIST)/latest/$(subst $(EXECUTABLE)-$(VERSION),$(EXECUTABLE)-latest,$(notdir $(file)));)
.PHONY: latest-check
latest-check:
cd $(DIST)/latest; $(foreach file,$(wildcard $(DIST)/latest/$(EXECUTABLE)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;)
.PHONY: publish
publish: release latest
.PHONY: bindata
bindata: modules/bindata/bindata.go
.IGNORE: modules/bindata/bindata.go
modules/bindata/bindata.go: $(BINDATA)
@which go-bindata > /dev/null; if [ $$? -ne 0 ]; then \
go get -u github.com/jteeuwen/go-bindata/...; \
fi
go-bindata -o=$@ -ignore="\\.go|README.md|TRANSLATORS" -pkg=bindata conf/...
go fmt $@
sed -i.bak 's/confLocaleLocale_/confLocaleLocale/' $@
rm $@.bak
.PHONY: javascripts
javascripts: public/js/index.js
@@ -131,5 +142,5 @@ stylesheets: public/css/index.css
public/css/index.css: $(STYLESHEETS)
lessc $< $@
.PHONY: generate
generate: bindata javascripts stylesheets
.PHONY: assets
assets: bindata javascripts stylesheets

View File

@@ -1,13 +1,13 @@
# Gitea - Git with a cup of tea
[![Build Status](https://travis-ci.org/go-gitea/gitea.svg?branch=master)](https://travis-ci.org/go-gitea/gitea)
[![codecov](https://codecov.io/gh/go-gitea/gitea/branch/master/graph/badge.svg)](https://codecov.io/gh/go-gitea/gitea)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-gitea/gitea)](https://goreportcard.com/report/github.com/go-gitea/gitea)
[![GoDoc](https://godoc.org/github.com/go-gitea/gitea?status.svg)](https://godoc.org/github.com/go-gitea/gitea)
[![](https://images.microbadger.com/badges/image/gitea/gitea.svg)](http://microbadger.com/images/gitea/gitea "Get your own image badge on microbadger.com")
[![Build Status](http://drone.gitea.io/api/badges/go-gitea/gitea/status.svg)](http://drone.gitea.io/go-gitea/gitea)
[![Join the chat at https://gitter.im/go-gitea/gitea](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-gitea/gitea?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![](https://images.microbadger.com/badges/image/gitea/gitea.svg)](http://microbadger.com/images/gitea/gitea "Get your own image badge on microbadger.com")
[![Coverage Status](https://coverage.gitea.io/badges/go-gitea/gitea/coverage.svg)](https://coverage.gitea.io/go-gitea/gitea)
[![Go Report Card](https://goreportcard.com/badge/code.gitea.io/gitea)](https://goreportcard.com/report/code.gitea.io/gitea)
[![GoDoc](https://godoc.org/code.gitea.io/gitea?status.svg)](https://godoc.org/code.gitea.io/gitea)
![](https://github.com/go-gitea/gitea/blob/master/public/img/gitea-large-resize.png?raw=true)
[![](public/img/gitea-large-resize.png)](https://github.com/go-gitea/gitea)
##### Status
@@ -21,7 +21,7 @@
### Important Notes
1. **YOU MUST READ THE [Contributors Guide](https://github.com/go-gitea/gitea/CONTRIBUTING.md) BEFORE STARTING TO WORK ON A PULL REQUEST**.
1. **YOU MUST READ THE [Contributors Guide](CONTRIBUTING.md) BEFORE STARTING TO WORK ON A PULL REQUEST**.
2. If you think there are vulnerabilities in the project, please talk privately to **security@gitea.io**. Thanks!
3. If you're interested in using APIs, we have experimental support with [documentation](https://godoc.org/github.com/go-gitea/go-sdk).
@@ -46,7 +46,7 @@ The goal of this project is to make the easiest, fastest, and most painless way
- Mail service
- Administration panel
- Supports MySQL, PostgreSQL, SQLite3 and [TiDB](https://github.com/pingcap/tidb) (experimental)
- Multi-language support ([19 languages](https://crowdin.com/project/gogs))
- Multi-language support ([20 languages](https://crowdin.com/project/gogs))
## System Requirements
@@ -63,10 +63,8 @@ The goal of this project is to make the easiest, fastest, and most painless way
**Note: As Gitea is a [Gogs](https://github.com/gogits/gogs) fork, tutorials and documentation related to gogs applies to Gitea too**
How to install Gitea:
_Do note that this Gitea branch is **not** stable enough for builds_
_Build from tags for the latest stable build, otherwise for development purposes, build from master_
- `go get code.gitea.io/gitea`
- go get code.gitea.io/gitea
- [Ship with Docker](https://github.com/go-gitea/gitea/tree/master/docker)
- [Install with Vagrant](https://github.com/go-gitea/examples/tree/master/vagrant)
@@ -124,11 +122,16 @@ _Build from tags for the latest stable build, otherwise for development purposes
- Thanks [DigitalOcean](https://www.digitalocean.com) for hosting home and demo sites.
- Thanks [KeyCDN](https://www.keycdn.com/) and [QiNiu](http://www.qiniu.com/) for providing CDN service.
## Contributors
- See [Maintainer](https://github.com/orgs/go-gitea/people)
- See [Contributors](https://github.com/go-gitea/gitea/graphs/contributors) for full list of contributors.
- See [Translators](conf/locale/TRANSLATORS) for public list of translators.
## Contributing
Fork -> Patch -> Push -> Pull Request
## Authors
* [Maintainers](https://github.com/orgs/go-gitea/people)
* [Contributors](https://github.com/go-gitea/gitea/graphs/contributors)
* [Translators](conf/locale/TRANSLATORS)
## License

View File

@@ -1,7 +1,6 @@
// +build cert
// Copyright 2009 The Go Authors. All rights reserved.
// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2016 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

View File

@@ -1,30 +0,0 @@
// +build !cert
// Copyright 2009 The Go Authors. All rights reserved.
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd
import (
"fmt"
"os"
"github.com/urfave/cli"
)
// CmdCert represents the available cert sub-command.
var CmdCert = cli.Command{
Name: "cert",
Usage: "Generate self-signed certificate",
Description: `Please use build tags "cert" to rebuild Gogs in order to have this ability`,
Action: runCert,
}
func runCert(*cli.Context) error {
fmt.Println("Command cert not available, please use build tags 'cert' to rebuild.")
os.Exit(1)
return nil
}

View File

@@ -12,9 +12,9 @@ import (
"path"
"time"
"github.com/Unknwon/cae/zip"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/setting"
"github.com/Unknwon/cae/zip"
"github.com/urfave/cli"
)
@@ -79,7 +79,6 @@ func runDump(ctx *cli.Context) error {
log.Printf("Packing dump files...")
z, err := zip.Create(fileName)
if err != nil {
os.Remove(fileName)
log.Fatalf("Fail to create %s: %v", fileName, err)
}
@@ -102,7 +101,7 @@ func runDump(ctx *cli.Context) error {
}
// FIXME: SSH key file.
if err = z.Close(); err != nil {
os.Remove(fileName)
_ = os.Remove(fileName)
log.Fatalf("Fail to save %s: %v", fileName, err)
}
@@ -111,7 +110,10 @@ func runDump(ctx *cli.Context) error {
}
log.Printf("Removing tmp work dir: %s", TmpWorkDir)
os.RemoveAll(TmpWorkDir)
if err := os.RemoveAll(TmpWorkDir); err != nil {
log.Fatalf("Fail to remove %s: %v", TmpWorkDir, err)
}
log.Printf("Finish dumping in file %s", fileName)
return nil

View File

@@ -13,13 +13,13 @@ import (
"strings"
"time"
"github.com/Unknwon/com"
"code.gitea.io/git"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/Unknwon/com"
gouuid "github.com/satori/go.uuid"
"github.com/urfave/cli"
)
@@ -51,7 +51,9 @@ func setup(logPath string) {
if setting.UseSQLite3 || setting.UseTiDB {
workDir, _ := setting.WorkDir()
os.Chdir(workDir)
if err := os.Chdir(workDir); err != nil {
log.GitLogger.Fatal(4, "Fail to change directory %s: %v", workDir, err)
}
}
models.SetEngine()
@@ -253,10 +255,14 @@ func runServ(c *cli.Context) error {
"User %s does not have level %v access to repository %s",
user.Name, requestedMode, repoPath)
}
os.Setenv("GITEA_PUSHER_NAME", user.Name)
}
}
uuid := gouuid.NewV4().String()
os.Setenv("GITEA_UUID", uuid)
// Keep the old env variable name for backward compability
os.Setenv("uuid", uuid)
// Special handle for Windows.

View File

@@ -49,7 +49,7 @@ func runUpdate(c *cli.Context) error {
}
task := models.UpdateTask{
UUID: os.Getenv("uuid"),
UUID: os.Getenv("GITEA_UUID"),
RefName: args[0],
OldCommitID: args[1],
NewCommitID: args[2],

View File

@@ -7,7 +7,6 @@ package cmd
import (
"crypto/tls"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/http/fcgi"
@@ -15,14 +14,14 @@ import (
"path"
"strings"
"code.gitea.io/git"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/bindata"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/public"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/template"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/routers"
"code.gitea.io/gitea/routers/admin"
apiv1 "code.gitea.io/gitea/routers/api/v1"
@@ -38,10 +37,7 @@ import (
"github.com/go-macaron/i18n"
"github.com/go-macaron/session"
"github.com/go-macaron/toolbox"
"github.com/go-xorm/xorm"
version "github.com/mcuadros/go-version"
"github.com/urfave/cli"
ini "gopkg.in/ini.v1"
macaron "gopkg.in/macaron.v1"
)
@@ -73,45 +69,6 @@ type VerChecker struct {
Expected string
}
// checkVersion checks if binary matches the version of templates files.
func checkVersion() {
// Templates.
data, err := ioutil.ReadFile(setting.StaticRootPath + "/templates/.VERSION")
if err != nil {
log.Fatal(4, "Fail to read 'templates/.VERSION': %v", err)
}
tplVer := string(data)
if tplVer != setting.AppVer {
if version.Compare(tplVer, setting.AppVer, ">") {
log.Fatal(4, "Binary version is lower than template file version, did you forget to recompile Gogs?")
} else {
log.Fatal(4, "Binary version is higher than template file version, did you forget to update template files?")
}
}
// Check dependency version.
checkers := []VerChecker{
{"github.com/go-xorm/xorm", func() string { return xorm.Version }, "0.5.5"},
{"github.com/go-macaron/binding", binding.Version, "0.3.2"},
{"github.com/go-macaron/cache", cache.Version, "0.1.2"},
{"github.com/go-macaron/csrf", csrf.Version, "0.1.0"},
{"github.com/go-macaron/i18n", i18n.Version, "0.3.0"},
{"github.com/go-macaron/session", session.Version, "0.1.6"},
{"github.com/go-macaron/toolbox", toolbox.Version, "0.1.0"},
{"gopkg.in/ini.v1", ini.Version, "1.8.4"},
{"gopkg.in/macaron.v1", macaron.Version, "1.1.7"},
{"code.gitea.io/git", git.Version, "0.4.1"},
}
for _, c := range checkers {
if !version.Compare(c.Version(), c.Expected, ">=") {
log.Fatal(4, `Dependency outdated!
Package '%s' current version (%s) is below requirement (%s),
please use following command to update this package and recompile Gogs:
go get -u %[1]s`, c.ImportPath, c.Version(), c.Expected)
}
}
}
// newMacaron initializes Macaron instance.
func newMacaron() *macaron.Macaron {
m := macaron.New()
@@ -123,11 +80,11 @@ func newMacaron() *macaron.Macaron {
m.Use(gzip.Gziper())
}
if setting.Protocol == setting.FCGI {
m.SetURLPrefix(setting.AppSubUrl)
m.SetURLPrefix(setting.AppSubURL)
}
m.Use(macaron.Static(
path.Join(setting.StaticRootPath, "public"),
macaron.StaticOptions{
m.Use(public.Static(
&public.Options{
Directory: path.Join(setting.StaticRootPath, "public"),
SkipLogging: setting.DisableRouterLog,
},
))
@@ -139,15 +96,8 @@ func newMacaron() *macaron.Macaron {
},
))
funcMap := template.NewFuncMap()
m.Use(macaron.Renderer(macaron.RenderOptions{
Directory: path.Join(setting.StaticRootPath, "templates"),
AppendDirectories: []string{path.Join(setting.CustomPath, "templates")},
Funcs: funcMap,
IndentJSON: macaron.Env != macaron.PROD,
}))
models.InitMailRender(path.Join(setting.StaticRootPath, "templates/mail"),
path.Join(setting.CustomPath, "templates/mail"), funcMap)
m.Use(templates.Renderer())
models.InitMailRender(templates.Mailer())
localeNames, err := bindata.AssetDir("conf/locale")
if err != nil {
@@ -158,7 +108,7 @@ func newMacaron() *macaron.Macaron {
localFiles[name] = bindata.MustAsset("conf/locale/" + name)
}
m.Use(i18n.I18n(i18n.Options{
SubURL: setting.AppSubUrl,
SubURL: setting.AppSubURL,
Files: localFiles,
CustomDirectory: path.Join(setting.CustomPath, "conf/locale"),
Langs: setting.Langs,
@@ -172,7 +122,7 @@ func newMacaron() *macaron.Macaron {
Interval: setting.CacheInterval,
}))
m.Use(captcha.Captchaer(captcha.Options{
SubURL: setting.AppSubUrl,
SubURL: setting.AppSubURL,
}))
m.Use(session.Sessioner(setting.SessionConfig))
m.Use(csrf.Csrfer(csrf.Options{
@@ -180,11 +130,11 @@ func newMacaron() *macaron.Macaron {
Cookie: setting.CSRFCookieName,
SetCookie: true,
Header: "X-Csrf-Token",
CookiePath: setting.AppSubUrl,
CookiePath: setting.AppSubURL,
}))
m.Use(toolbox.Toolboxer(m, toolbox.Options{
HealthCheckFuncs: []*toolbox.HealthCheckFuncDesc{
&toolbox.HealthCheckFuncDesc{
{
Desc: "Database connection",
Func: models.Ping,
},
@@ -199,7 +149,6 @@ func runWeb(ctx *cli.Context) error {
setting.CustomConf = ctx.String("config")
}
routers.GlobalInit()
checkVersion()
m := newMacaron()
@@ -216,7 +165,7 @@ func runWeb(ctx *cli.Context) error {
m.Get("/", ignSignIn, routers.Home)
m.Group("/explore", func() {
m.Get("", func(ctx *context.Context) {
ctx.Redirect(setting.AppSubUrl + "/explore/repos")
ctx.Redirect(setting.AppSubURL + "/explore/repos")
})
m.Get("/repos", routers.ExploreRepos)
m.Get("/users", routers.ExploreUsers)
@@ -280,7 +229,7 @@ func runWeb(ctx *cli.Context) error {
m.Group("/users", func() {
m.Get("", admin.Users)
m.Combo("/new").Get(admin.NewUser).Post(bindIgnErr(auth.AdminCrateUserForm{}), admin.NewUserPost)
m.Combo("/new").Get(admin.NewUser).Post(bindIgnErr(auth.AdminCreateUserForm{}), admin.NewUserPost)
m.Combo("/:userid").Get(admin.EditUser).Post(bindIgnErr(auth.AdminEditUserForm{}), admin.EditUserPost)
m.Post("/:userid/delete", admin.DeleteUser)
})
@@ -336,11 +285,7 @@ func runWeb(ctx *cli.Context) error {
}
defer fr.Close()
ctx.Header().Set("Cache-Control", "public,max-age=86400")
ctx.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, attach.Name))
// Fix #312. Attachments with , in their name are not handled correctly by Google Chrome.
// We must put the name in " manually.
if err = repo.ServeData(ctx, "\""+attach.Name+"\"", fr); err != nil {
if err = repo.ServeData(ctx, attach.Name, fr); err != nil {
ctx.Handle(500, "ServeData", err)
return
}
@@ -584,7 +529,7 @@ func runWeb(ctx *cli.Context) error {
m.Group("/pulls/:index", func() {
m.Get("/commits", context.RepoRef(), repo.ViewPullCommits)
m.Get("/files", context.RepoRef(), repo.SetEditorconfigIfExists, repo.ViewPullFiles)
m.Get("/files", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ViewPullFiles)
m.Post("/merge", reqRepoWriter, repo.MergePullRequest)
}, repo.MustAllowPulls)
@@ -592,12 +537,12 @@ func runWeb(ctx *cli.Context) error {
m.Get("/src/*", repo.SetEditorconfigIfExists, repo.Home)
m.Get("/raw/*", repo.SingleDownload)
m.Get("/commits/*", repo.RefCommits)
m.Get("/commit/:sha([a-f0-9]{7,40})$", repo.SetEditorconfigIfExists, repo.Diff)
m.Get("/commit/:sha([a-f0-9]{7,40})$", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.Diff)
m.Get("/forks", repo.Forks)
}, context.RepoRef())
m.Get("/commit/:sha([a-f0-9]{7,40})\\.:ext(patch|diff)", repo.RawDiff)
m.Get("/compare/:before([a-z0-9]{40})\\.\\.\\.:after([a-z0-9]{40})", repo.CompareDiff)
m.Get("/compare/:before([a-z0-9]{40})\\.\\.\\.:after([a-z0-9]{40})", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.CompareDiff)
}, ignSignIn, context.RepoAssignment(), repo.MustBeNotBare)
m.Group("/:username/:reponame", func() {
m.Get("/stars", repo.Stars)
@@ -617,6 +562,8 @@ func runWeb(ctx *cli.Context) error {
})
// ***** END: Repository *****
m.Get("/notifications", reqSignIn, user.Notifications)
m.Group("/api", func() {
apiv1.RegisterRoutes(m)
}, ignSignIn)
@@ -635,17 +582,17 @@ func runWeb(ctx *cli.Context) error {
// Flag for port number in case first time run conflict.
if ctx.IsSet("port") {
setting.AppUrl = strings.Replace(setting.AppUrl, setting.HTTPPort, ctx.String("port"), 1)
setting.AppURL = strings.Replace(setting.AppURL, setting.HTTPPort, ctx.String("port"), 1)
setting.HTTPPort = ctx.String("port")
}
var listenAddr string
if setting.Protocol == setting.UNIX_SOCKET {
if setting.Protocol == setting.UnixSocket {
listenAddr = fmt.Sprintf("%s", setting.HTTPAddr)
} else {
listenAddr = fmt.Sprintf("%s:%s", setting.HTTPAddr, setting.HTTPPort)
}
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubUrl)
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL)
var err error
switch setting.Protocol {
@@ -656,9 +603,10 @@ func runWeb(ctx *cli.Context) error {
err = server.ListenAndServeTLS(setting.CertFile, setting.KeyFile)
case setting.FCGI:
err = fcgi.Serve(nil, m)
case setting.UNIX_SOCKET:
os.Remove(listenAddr)
case setting.UnixSocket:
if err := os.Remove(listenAddr); err != nil {
log.Fatal(4, "Fail to remove unix socket directory %s: %v", listenAddr, err)
}
var listener *net.UnixListener
listener, err = net.ListenUnix("unix", &net.UnixAddr{Name: listenAddr, Net: "unix"})
if err != nil {

View File

@@ -400,8 +400,8 @@ DEFAULT_INTERVAL = 8
MAX_RESPONSE_ITEMS = 50
[i18n]
LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP
NAMES = English,简体中文,繁體中文(香港),繁體中文(台湾),Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,Polski,български,Italiano,Suomalainen,Türkçe,čeština,Српски
LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE
NAMES = English,简体中文,繁體中文(香港),繁體中文(台湾),Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,Polski,български,Italiano,Suomalainen,Türkçe,čeština,Српски,Svenska
; Used for datetimepicker
[i18n.datelang]
@@ -423,6 +423,8 @@ it-IT = it
fi-FI = fi
tr-TR = tr
cs-CZ = cs-CZ
sr-SP = sr
sv-SE = sv
; Extension mapping to highlight class
; e.g. .toml=ini

View File

@@ -47,7 +47,7 @@ cancel=Отказ
[install]
install=Инсталация
title=Стъпки за инсталиране при първоначално стартиране
docker_helper=Ако Gitea е стартиран в Docker контейнер, моля прочетете <a target="_blank" href="%s">нашите указания</a> внимателно, преди да правите промени по настройките на тази страница!
docker_helper=Ако Gitea е стартиран в Docker контейнер, моля прочетете <a target="_blank" rel="noopener" href="%s">нашите указания</a> внимателно, преди да правите промени по настройките на тази страница!
requite_db_desc=Gitea изисква MySQL, PostgreSQL, SQLite3 или TiDB.
db_title=Настройки на базата данни
db_type=Тип на база данни
@@ -351,7 +351,7 @@ visibility=Видимост
visiblity_helper=Това хранилище е <span class="ui red text">Частно</span>
visiblity_helper_forced=Административна настройка задължава всички нови хранилища да бъдат <span class="ui red text">Частни</span>
visiblity_fork_helper=(Промяна на тази стойност ще се отрази на всички разклонения)
clone_helper=Нуждаете се от помощ при клониране? Посетете <a target="_blank" href="%s">Помощ</a>!
clone_helper=Нуждаете се от помощ при клониране? Посетете <a target="_blank" rel="noopener" href="%s">Помощ</a>!
fork_repo=Разклони хранилището
fork_from=Разклонение от
fork_visiblity_helper=Не може да променяте видимостта на разклонено хранилище.
@@ -457,7 +457,7 @@ editor.branch_already_exists=Клон '%s' вече съществува в то
editor.directory_is_a_file=Частта '%s' в пътя е файл, не директория в това хранилище.
editor.filename_is_a_directory=Име '%s' вече съществува като директория в това хранилище.
editor.file_editing_no_longer_exists=Файл '%s' който редактирате вече не съществува в това хранилище.
editor.file_changed_while_editing=Съдържанието на файла е било променено докато правихте редакциите. <a target="_blank" href="%s">Щракнете тук</a> за да прегледате какво е променено или <strong>натиснете Запис на ревизия</strong> отново за да презапишете чуждите промени.
editor.file_changed_while_editing=Съдържанието на файла е било променено докато правихте редакциите. <a target="_blank" rel="noopener" href="%s">Щракнете тук</a> за да прегледате какво е променено или <strong>натиснете Запис на ревизия</strong> отново за да презапишете чуждите промени.
editor.file_already_exists=Файл с име '%s' вече съществува в това хранилище.
editor.no_changes_to_show=Няма промени.
editor.fail_to_update_file=Невъзможно модифициране/създаване на файл '%s' заради грешка: %v
@@ -690,7 +690,7 @@ settings.search_user_placeholder=Име на потребител...
settings.org_not_allowed_to_be_collaborator=Невъзможно добавяне на организация като сътрудник.
settings.user_is_org_member=Потребителят вече участва в организацията и не може да бъде добавен като сътрудник.
settings.add_webhook=Добави уеб-кука
settings.hooks_desc=Уеб-куките много приличат на обикновен HTTP POST тригер. Когато нещо се случи в Gitea, ние ще изпратим уведомление до сървъра, който посочите. Научете повече в <a target="_blank" href="%s">Ръководство за уеб-куки</a>.
settings.hooks_desc=Уеб-куките много приличат на обикновен HTTP POST тригер. Когато нещо се случи в Gitea, ние ще изпратим уведомление до сървъра, който посочите. Научете повече в <a target="_blank" rel="noopener" href="%s">Ръководство за уеб-куки</a>.
settings.webhook_deletion=Изтрий уеб-кука
settings.webhook_deletion_desc=При изтриване на тази уеб-кука ще се премахне информацията за нея и цялата хронология на нейното изпращане. Желаете ли да продължите?
settings.webhook_deletion_success=Уеб-куката е изтрита успешно!
@@ -707,7 +707,7 @@ settings.githook_edit_desc=Ако куката е неактивна, ще бъ
settings.githook_name=Име на куката
settings.githook_content=Съдържание на куката
settings.update_githook=Запази куката
settings.add_webhook_desc=Gitea ще изпрати <code>POST</code> заявка към указания URL адрес заедно с информация за събитието, което е настъпило. Също можете да укажете в какъв формат желаете да получите данните при задействане на куката (JSON, x-www-form-urlencoded, XML) и др. Допълнително описание можете да намерите в нашето <a target="_blank" href="%s">Ръководство за уеб-куки</a>.
settings.add_webhook_desc=Gitea ще изпрати <code>POST</code> заявка към указания URL адрес заедно с информация за събитието, което е настъпило. Също можете да укажете в какъв формат желаете да получите данните при задействане на куката (JSON, x-www-form-urlencoded, XML) и др. Допълнително описание можете да намерите в нашето <a target="_blank" rel="noopener" href="%s">Ръководство за уеб-куки</a>.
settings.payload_url=URL адрес на изпращане
settings.content_type=Тип на съдържанието
settings.secret=Тайна

View File

@@ -47,7 +47,7 @@ cancel=Zrušit
[install]
install=Instalace
title=Kroky instalace pro první běh
docker_helper=Spouštíte-li Gitea uvnitř Dockeru, přečtěte si prosím pečlivě <a target="_blank" href="%s">návod</a>, než něco změníte na této stránce!
docker_helper=Spouštíte-li Gitea uvnitř Dockeru, přečtěte si prosím pečlivě <a target="_blank" rel="noopener" href="%s">návod</a>, než něco změníte na této stránce!
requite_db_desc=Gitea vyžaduje MySQL, PostgreSQL, SQLite3 nebo TiDB.
db_title=Nastavení databáze
db_type=Typ databáze
@@ -126,7 +126,7 @@ uname_holder=Uživatelské jméno nebo e-mailová adresa
password_holder=Heslo
switch_dashboard_context=Přepnout kontext přehledu
my_repos=Mé repositáře
show_more_repos=Show more repositories...
show_more_repos=Zobrazit více repositářů...
collaborative_repos=Společné repositáře
my_orgs=Mé organizace
my_mirrors=Má zrcadla
@@ -151,7 +151,7 @@ forget_password=Zapomněli jste heslo?
sign_up_now=Potřebujete účet? Zaregistrujte se.
confirmation_mail_sent_prompt=Nový potvrzovací e-mail byl zaslán na <b>%s</b>, prosíme, zkontrolujte si vaši doručenou poštu během následující %d hodin pro dokončení registračního procesu.
active_your_account=Aktivujte si váš účet
prohibit_login=Login Prohibited
prohibit_login=Přihlášení zakázáno
prohibit_login_desc=Vašemu účtu je zakázáno se přihlásit, kontaktujte prosím správce webu.
resent_limit_prompt=Omlouváme se, ale před chvílí jste požádal o aktivační e-mail. Prosíme, počkejte 3 minuty a pak to zkuste znovu.
has_unconfirmed_mail=Zdravím, %s, máte nepotvrzenou e-mailovou adresu (<b>%s</b>). Pokud jste nedostali e-mail pro potvrzení nebo potřebujete zaslat nový, klikněte prosím na tlačítku níže.
@@ -190,11 +190,11 @@ AuthName=Název ověření
AdminEmail=E-mailová adresa správce
NewBranchName=Název nové větve
CommitSummary=Commit summary
CommitMessage=Commit message
CommitChoice=Commit choice
CommitSummary=Shrnutí revize
CommitMessage=Zpráva revize
CommitChoice=Výběr revize
TreeName=Cesta k souboru
Content=Content
Content=Obsah
require_error=` nemůže být prázdný.`
alpha_dash_error=` musí být pouze písmena, číslice či znaky - a _ .`
@@ -232,7 +232,7 @@ org_still_own_repo=Tato organizace stále vlastní repositáře, musíte je nejd
target_branch_not_exist=Cílová větev neexistuje.
[user]
change_avatar=Change your avatar
change_avatar=Změnit vaši uživatelskou ikonu
join_on=Připojil se dne
repositories=Repositáře
activity=Veřejná aktivita
@@ -248,7 +248,7 @@ form.name_pattern_not_allowed=Vzor uživatelského jména '%s' není povolen.
[settings]
profile=Profil
password=Heslo
avatar=Avatar
avatar=Uživatelská ikona
ssh_keys=Klíče SSH
social=Sociální účty
applications=Aplikace
@@ -269,7 +269,7 @@ change_username_prompt=Tato změna ovlivní vztah odkazů k vašemu účtu.
continue=Pokračovat
cancel=Zrušit
lookup_avatar_by_mail=Vyhledávat Avatar podle emailu
lookup_avatar_by_mail=Vyhledávat uživatelskou ikonu podle emailu
federated_avatar_lookup=Federated Avatar Lookup
enable_custom_avatar=Povolit uživatelskou ikonu uživatele
choose_new_avatar=Vybrat novou ikonu uživatele
@@ -351,13 +351,13 @@ visibility=Viditelnost
visiblity_helper=Tento repositář je <span class="ui red text">soukromý</span>
visiblity_helper_forced=Správce vynutil na všech nových repositářích, aby byly <span class="ui red text">soukromé</span>
visiblity_fork_helper=(Změna této hodnoty ovlivní všechny repositáře rozštěpení)
clone_helper=Potřebujete pomoci s klonováním? Navštivte <a target="_blank" href="%s">nápovědu</a>!
clone_helper=Potřebujete pomoci s klonováním? Navštivte <a target="_blank" rel="noopener" href="%s">nápovědu</a>!
fork_repo=Repositář rozštěpení
fork_from=Rozštěpit z
fork_visiblity_helper=Nemůžete změnit viditelnost repositáře rozštěpení.
repo_desc=Popis
repo_lang=Jazyk
repo_gitignore_helper=Select .gitignore templates
repo_gitignore_helper=Vyberte šablony .gitignore
license=Licence
license_helper=Vyberte licenční soubor
readme=Soubor README
@@ -365,12 +365,12 @@ readme_helper=Vyberte šablonu souboru README
auto_init=Inicializovat tento repositář s vybranými soubory a šablonou
create_repo=Vytvořit repositář
default_branch=Výchozí větev
mirror_prune=Prune
mirror_prune=Vyčistit
mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
mirror_interval=Odstup zrcadlení (hodina)
mirror_address=Adresa zrcadla
mirror_address_desc=Prosím, přidejte do adresy potřebné přihlašovací údaje.
mirror_last_synced=Last Synced
mirror_last_synced=Naposledy synchronizováno
watchers=Sledující
stargazers=Sledující
forks=Rozštěpení
@@ -427,43 +427,43 @@ file_view_raw=Zobrazit v surovém stavu
file_permalink=Trvalý odkaz
file_too_large=Tento soubor je příliš velký pro zobrazení
editor.new_file=New file
editor.upload_file=Upload file
editor.edit_file=Edit file
editor.preview_changes=Preview Changes
editor.new_file=Nový soubor
editor.upload_file=Nahrát soubor
editor.edit_file=Upravit soubor
editor.preview_changes=Náhled změn
editor.cannot_edit_non_text_files=Netextové soubory není možné upravovat
editor.edit_this_file=Edit this file
editor.must_be_on_a_branch=You must be on a branch to make or propose changes to this file
editor.fork_before_edit=You must fork this repository before editing the file
editor.edit_this_file=Upravit tento soubor
editor.must_be_on_a_branch=Musíte mít zvolenu větev pro úpravu či návrh změn tohoto souboru
editor.fork_before_edit=Musíte provést rozvětvení repositáře před úpravou souboru
editor.delete_this_file=Odstranit tento soubor
editor.must_have_write_access=Musíte mít přístup pro zápis pro dělání či navrhování změn tohoto souboru
editor.file_delete_success=Soubor '%s' byl úspěšně odstraněn!
editor.name_your_file=Name your file...
editor.name_your_file=Pojmenujte váš soubor...
editor.filename_help=To add directory, just type it and press /. To remove a directory, go to the beginning of the field and press backspace.
editor.or=nebo
editor.cancel_lower=cancel
editor.commit_changes=Commit Changes
editor.add_tmpl=Add '%s/<filename>'
editor.add=Add '%s'
editor.cancel_lower=zrušit
editor.commit_changes=Uložit změny revize
editor.add_tmpl=Přidat '%s/<nazev_souboru>'
editor.add=Přidat '%s'
editor.update=Aktualizovat "%s"
editor.delete=Delete '%s'
editor.commit_message_desc=Add an optional extended description...
editor.commit_directly_to_this_branch=Commit directly to the <strong class="branch-name">%s</strong> branch.
editor.create_new_branch=Create a <strong>new branch</strong> for this commit and start a pull request.
editor.delete=Smazat '%s'
editor.commit_message_desc=Přidat dobrovolný rozšířený popis...
editor.commit_directly_to_this_branch=Uložte změny revize přímo do větve <strong class="branch-name">%s</strong>.
editor.create_new_branch=Vytvořit <strong>novou větev</strong> pro tuto revizi a spustit požadavek na stažení.
editor.new_branch_name_desc=Nový název větve...
editor.cancel=Zrušit
editor.filename_cannot_be_empty=Filename cannot be empty.
editor.branch_already_exists=Branch '%s' already exists in this repository.
editor.filename_cannot_be_empty=Název souboru nemůže být prázdný.
editor.branch_already_exists=Repositář větev '%s' již obsahuje.
editor.directory_is_a_file=Entry '%s' in the parent path is a file not a directory in this repository.
editor.filename_is_a_directory=The filename '%s' is an existing directory in this repository.
editor.file_editing_no_longer_exists=The file '%s' you are editing no longer exists in the repository.
editor.file_changed_while_editing=Obsah souboru se změnil od začátku úprav. <a target="_blank" href="%s"> Klepnutím sem</a> zobrazíte, co se změnilo, nebo <strong>stiskněte potvrdit znovu</strong> pro přepsání změn.
editor.file_changed_while_editing=Obsah souboru se změnil od začátku úprav. <a target="_blank" rel="noopener" href="%s"> Klepnutím sem</a> zobrazíte, co se změnilo, nebo <strong>stiskněte potvrdit znovu</strong> pro přepsání změn.
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.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'
editor.add_subdir=Přidat podadresář...
editor.unable_to_upload_files=Nepodařilo se nahrát soubor '%s'. Chyba: %v
editor.upload_files_to_dir=Nahrát soubory do '%s'
commits.commits=Revize
commits.search=Hledání revizí
@@ -490,11 +490,11 @@ issues.create=Vytvořit úkol
issues.new_label=Nový štítek
issues.new_label_placeholder=Název štítku...
issues.create_label=Vytvořit štítek
issues.label_templates.title=Load a predefined set of labels
issues.label_templates.info=There arent any labels yet. You can click on the "New Label" button above to create one or use a predefined set below.
issues.label_templates.helper=Select a label set
issues.label_templates.use=Use this label set
issues.label_templates.fail_to_load_file=Failed to load label template file '%s': %v
issues.label_templates.title=Nahrát předdefinovanou sadu značek
issues.label_templates.info=Nejsou zadány žádné značky. Pro vytvoření nové klikněte na tlačítko Nová značka nebo použijte předdefinovanou sadu.
issues.label_templates.helper=Vyberte sadu značek
issues.label_templates.use=Použít tuto sadu značek
issues.label_templates.fail_to_load_file=Nepodařilo se nahrát soubor šablony značek '%s': %v
issues.open_tab=%d otevřených
issues.close_tab=%d zavřených
issues.filter_label=Štítek
@@ -522,8 +522,8 @@ issues.next=Další
issues.open_title=otevřený
issues.closed_title=zavřený
issues.num_comments=%d komentářů
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=`okomentoval <a href="#%s">%s</a>`
issues.delete_comment_confirm=Jste si jist, že chcete smazat tento komentář?
issues.no_content=Není zde žádný obsah.
issues.close_issue=Zavřít
issues.close_comment_issue=Okomentovat a zavřít
@@ -536,7 +536,7 @@ issues.commit_ref_at=`odkázal na tento úkol z revize <a id="%[1]s" href="#%[1]
issues.poster=Autor
issues.collaborator=Spolupracovník
issues.owner=Vlastník
issues.sign_in_require_desc=<a href="%s">Sign in</a> to join this conversation.
issues.sign_in_require_desc=<a href="%s">Přihlašte se</a> pro zapojení do konverzace.
issues.edit=Upravit
issues.cancel=Zrušit
issues.save=Uložit
@@ -551,8 +551,8 @@ issues.label_deletion=Smazání štítku
issues.label_deletion_desc=Smazání tohoto štítku jej smaže také ze všech návazných úkolech. Chcete pokračovat?
issues.label_deletion_success=Štítek byl úspěšně smazán!
issues.num_participants=%d účastníků
issues.attachment.open_tab=`Click to see "%s" in a new tab`
issues.attachment.download=`Click to download "%s"`
issues.attachment.open_tab=`Klikněte pro zobrazení "%s" v nové záložce`
issues.attachment.download=`Klikněte pro stažení "%s"`
pulls.new=Nový požadavek na natažení
pulls.compare_changes=Porovnat změny
@@ -625,32 +625,32 @@ wiki.last_updated=Naposledy aktualizováno: %s
settings=Nastavení
settings.options=Možnosti
settings.collaboration=Spolupráce
settings.collaboration.admin=Admin
settings.collaboration.write=Write
settings.collaboration.read=Read
settings.collaboration.undefined=Undefined
settings.collaboration.admin=Správce
settings.collaboration.write=Zápis
settings.collaboration.read=Čtení
settings.collaboration.undefined=Neurčeno
settings.hooks=Webové háčky
settings.githooks=Háčky Gitu
settings.basic_settings=Základní nastavení
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=Nastavení zrcadla
settings.sync_mirror=Provést synchronizaci
settings.mirror_sync_in_progress=Synchronizace zrcadel probíhá, prosím načtěte znovu stránku přibližně za minutu.
settings.site=Oficiální stránky
settings.update_settings=Změnit nastavení
settings.change_reponame_prompt=Tato změna ovlivní vztah odkazů k repositáři.
settings.advanced_settings=Pokročilá nastavení
settings.wiki_desc=Enable wiki system
settings.use_internal_wiki=Use builtin wiki
settings.wiki_desc=Povolit systém Wiki
settings.use_internal_wiki=Použít vestavěný systém Wiki
settings.use_external_wiki=Používat externí Wiki
settings.external_wiki_url=URL externí Wiki
settings.external_wiki_url_desc=Návštěvníci budou při kliknutí na záložku přesměrování na tuto URL.
settings.issues_desc=Enable issue tracker
settings.use_internal_issue_tracker=Use builtin lightweight issue tracker
settings.issues_desc=Povolit systém úkolů
settings.use_internal_issue_tracker=Povolit věstavěný odlehčený systém úkolů
settings.use_external_issue_tracker=Použít externí systém úkolů
settings.tracker_url_format=Formát URL externího systému úkolů
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=Styl pojmenování externího systému úkolů:
settings.tracker_issue_style.numeric=Číselný
settings.tracker_issue_style.alphanumeric=Alfanumeric
settings.tracker_url_format_desc=Můžete použít zástupné výrazy <code>{user} {repo} {index}</code> pro uživatelské jméno, název repositáře a index úkolu.
settings.pulls_desc=Povolit požadavky na stažení, aby veřejné příspěvky mohly být akceptovány
settings.danger_zone=Nebezpečná zóna
@@ -690,7 +690,7 @@ settings.search_user_placeholder=Hledat uživatele...
settings.org_not_allowed_to_be_collaborator=Není dovoleno přidat organizaci jako spolupracovníka.
settings.user_is_org_member=Uživatel je již členem organizace, tudíž nemůže být přidán jako spolupracovník.
settings.add_webhook=Přidat webový háček
settings.hooks_desc=Webové háčky jsou podobné základním spouštím HTTP POST událostí. Kdykoliv se něco stane v Gitea, bude postaráno o oznámení specifikovanému cílovému serveru. Více se o daném dozvíte v <a target="_blank" href="%s">příručce webových háčků</a>.
settings.hooks_desc=Webové háčky jsou podobné základním spouštím HTTP POST událostí. Kdykoliv se něco stane v Gitea, bude postaráno o oznámení specifikovanému cílovému serveru. Více se o daném dozvíte v <a target="_blank" rel="noopener" href="%s">příručce webových háčků</a>.
settings.webhook_deletion=Smazat webový háček
settings.webhook_deletion_desc=Smazáním tohoto webového háčku dojte také ke smazání veškerých informací o něm a také historie volání. Chcete pokračovat?
settings.webhook_deletion_success=Webový háček byl úspěšně smazán!
@@ -707,7 +707,7 @@ settings.githook_edit_desc=Je-li háček neaktivní, bude zobrazen vzorový obsa
settings.githook_name=Název háčku
settings.githook_content=Obsah háčku
settings.update_githook=Upravit háček
settings.add_webhook_desc=Gitea zašle požadavek typu <code>POST</code> na zadanou URL, společně s informacemi o události, která nastala. Můžete také specifikovat, jaký datový formát se má použít po spuštění daného háčku (JSON, x-www-form-urlencoded, XML atp.). Více informací je k nalezení v našem <a target="_blank" href="%s">Návodu na webové háčky</a>.
settings.add_webhook_desc=Gitea zašle požadavek typu <code>POST</code> na zadanou URL, společně s informacemi o události, která nastala. Můžete také specifikovat, jaký datový formát se má použít po spuštění daného háčku (JSON, x-www-form-urlencoded, XML atp.). Více informací je k nalezení v našem <a target="_blank" rel="noopener" href="%s">Návodu na webové háčky</a>.
settings.payload_url=URL obsahu
settings.content_type=Typ obsahu
settings.secret=Tajný klíč
@@ -720,7 +720,7 @@ settings.event_send_everything=Potřebuji <strong>vše</strong>.
settings.event_choose=Nech mne vybrat, co potřebuji.
settings.event_create=Vytvořit
settings.event_create_desc=Větev nebo značka byla vytvořena
settings.event_pull_request=Pull Request
settings.event_pull_request=Požadavek na stažení
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, or synchronized.
settings.event_push=Nahrát
settings.event_push_desc=Nahrání pomocí Gitu do repositáře
@@ -760,7 +760,7 @@ diff.stats_desc=<strong> %d změnil soubory</strong>, kde provedl <strong>%d př
diff.bin=binární
diff.view_file=Zobrazit soubor
diff.file_suppressed=File diff suppressed because it is too large
diff.too_many_files=Some files were not shown because too many files changed in this diff
diff.too_many_files=Některé soubory nejsou zobrazny, neboť je v této revizi změněno mnoho souborů
release.releases=Vydání
release.new_release=Nové vydání
@@ -791,7 +791,7 @@ release.deletion=Smazání vydání
release.deletion_desc=Smazáním tohoto vydání se také smaže odpovídající značka. Chcete pokračovat?
release.deletion_success=Vydání bylo úspěšně smazáno!
release.tag_name_already_exist=Vydání s touto značkou již existuje.
release.tag_name_invalid=Tag name is not valid.
release.tag_name_invalid=Název štítku není platný.
release.downloads=Soubory ke stažení
[org]
@@ -959,7 +959,7 @@ users.edit_account=Upravit účet
users.max_repo_creation=Limit počtu vytvořených repositářů
users.max_repo_creation_desc=(Nastavte na -1 pro použití výchozího systémového limitu)
users.is_activated=Tento účet je aktivován
users.prohibit_login=This account is prohibited to login
users.prohibit_login=Tento účet má zakázáno přihlášení
users.is_admin=Tento účet je správce
users.allow_git_hook=Tento účet má právo vytváře háčky Gitu
users.allow_import_local=Tento účet má právo importovat místní repositáře
@@ -990,7 +990,7 @@ auths.enabled=Povolený
auths.updated=Upravený
auths.auth_type=Typ ověření
auths.auth_name=Název ověření
auths.security_protocol=Security Protocol
auths.security_protocol=Protokol zabezpečení
auths.domain=Doména
auths.host=Server
auths.port=Port
@@ -1115,17 +1115,17 @@ config.picture_service=Služba ikon uživatelů
config.disable_gravatar=Zakázat službu Gravatar
config.enable_federated_avatar=Enable Federated Avatars
config.git_config=Git Configuration
config.git_disable_diff_highlight=Disable Diff Syntax Highlight
config.git_max_diff_lines=Max Diff Lines (for a single file)
config.git_max_diff_line_characters=Max Diff Characters (for a single line)
config.git_max_diff_files=Max Diff Files (to be shown)
config.git_gc_args=GC Arguments
config.git_migrate_timeout=Migration Timeout
config.git_mirror_timeout=Mirror Update Timeout
config.git_clone_timeout=Clone Operation Timeout
config.git_pull_timeout=Pull Operation Timeout
config.git_gc_timeout=GC Operation Timeout
config.git_config=Konfigurace Gitu
config.git_disable_diff_highlight=Zakázat zvýraznění syntaxe v rozdílovém zobrazení
config.git_max_diff_lines=Maximální počet rozdílových řádků jednoho souboru
config.git_max_diff_line_characters=Maximální počet zobrazených rozdílových znaků
config.git_max_diff_files=Maximální počet zobrazených rozdílových souborů
config.git_gc_args=Parametry GC
config.git_migrate_timeout=Časový limit migrace
config.git_mirror_timeout=Časový limit aktualizace zrcadla
config.git_clone_timeout=Časový limit operace naklonování
config.git_pull_timeout=Časový limit operace stažení
config.git_gc_timeout=Časový limit operace GC
config.log_config=Nastavení logů
config.log_mode=Způsob logování

View File

@@ -47,7 +47,7 @@ cancel=Abbrechen
[install]
install=Installation
title=Installationsschritte für den ersten Start
docker_helper=Wenn Gitea innerhalb von Docker läuft, lesen Sie sich bitte den <a target="_blank" href="%s">Leitfaden</a> genau durch, bevor Sie irgendwas auf dieser Seite ändern!
docker_helper=Wenn Gitea innerhalb von Docker läuft, lesen Sie sich bitte den <a target="_blank" rel="noopener" href="%s">Leitfaden</a> genau durch, bevor Sie irgendwas auf dieser Seite ändern!
requite_db_desc=Gitea benötigt MySQL, PostgreSQL, SQLite3 oder TiDB.
db_title=Datenbankeinstellungen
db_type=Datenbanktyp
@@ -76,7 +76,7 @@ domain_helper=Dies hat Auswirkung auf die SSH Klon-URLs.
ssh_port=SSH Port
ssh_port_helper=Der Port Ihres SSH-Servers. Leer lassen um SSH zu deaktivieren.
http_port=HTTP Port
http_port_helper=Auf dieser Port Nummer wird Gitea erreichbar sein.
http_port_helper=Auf diesem Port wird Gitea erreichbar sein.
app_url=Anwendungs-URL
app_url_helper=Dies hat Auswirkung auf die HTTP/HTTPS Klon-URLs und den Inhalt der E-Mails.
log_root_path=Logdateipfad
@@ -351,7 +351,7 @@ visibility=Sichtbarkeit
visiblity_helper=Dieses Repository ist <span class="ui red text">privat</span>
visiblity_helper_forced=Der Administrator hat festgelegt, dass alle neuen Repositories <span class="ui red text">privat</span> sein müssen
visiblity_fork_helper=(Eine Änderung dieses Wertes wirkt sich auf alle Forks aus)
clone_helper=Sie brauchen Hilfe beim Klonen? Öffnen Sie die <a target="_blank" href="%s">Hilfe</a>!
clone_helper=Sie brauchen Hilfe beim Klonen? Öffnen Sie die <a target="_blank" rel="noopener" href="%s">Hilfe</a>!
fork_repo=Repository forken
fork_from=Fork von
fork_visiblity_helper=Die Sichtbarkeit von geforkten Repositories ist nicht veränderbar.
@@ -401,6 +401,7 @@ watch=Beobachten
unstar=Favorit entfernen
star=Favorit hinzufügen
fork=Fork
download_archive=Dieses Repository herunterladen
no_desc=Keine Beschreibung
quick_guide=Kurzanleitung
@@ -432,32 +433,32 @@ editor.upload_file=Datei hochladen
editor.edit_file=Datei bearbeiten
editor.preview_changes=Vorschau der Änderungen
editor.cannot_edit_non_text_files=Nicht-Text Dateien können nicht bearbeitet werden
editor.edit_this_file=Diese Datei bearbeiten
editor.must_be_on_a_branch=Du musst dich in einer Branch befinden um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen
editor.fork_before_edit=Um die Datei zu bearbeiten müssen Sie das Repository forken
editor.delete_this_file=Diese Datei löschen
editor.must_have_write_access=Du musst Schreibzugriff haben um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen
editor.edit_this_file=Datei bearbeiten
editor.must_be_on_a_branch=Sie müssen sich in einem Branch befinden, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen
editor.fork_before_edit=Um die Datei zu bearbeiten, müssen Sie das Repository forken
editor.delete_this_file=Datei löschen
editor.must_have_write_access=Du musst Schreibzugriff haben, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen
editor.file_delete_success=Die Datei '%s' wurde erfolgreich gelöscht!
editor.name_your_file=Dateinamen eingeben...
editor.filename_help=Um einen Ordner hinzuzufügen, gib den Namen ein und drücke /. Um einen Ordner zu entfernen, gehe zum Anfang des Feldes und drücke auf die Rücktaste.
editor.or=oder
editor.cancel_lower=abbrechen
editor.commit_changes=Änderungen im Commit
editor.commit_changes=Änderungen einchecken
editor.add_tmpl=Hinzufügen von '%s/<filename>'
editor.add='%s' hinzufügen
editor.update='%s' ändern
editor.delete='%s' löschen
editor.commit_message_desc=Eine optionale, erweiterte Commit Beschreibung...
editor.commit_directly_to_this_branch=Änderungen direkt dem Branch <strong class="branch-name">%s</strong> hinzufügen.
editor.create_new_branch=Erstellen Sie einen <strong>neuen Branch</strong> für diesen Commit und starten Sie einen Pull Request.
editor.commit_message_desc=Eine ausführlichere Beschreibung kann hinzugefügt werden...
editor.commit_directly_to_this_branch=Direkt in den <strong class="branch-name">%s</strong> Branch einchecken.
editor.create_new_branch=Einen <strong>neuen Branch</strong> für diesen Commit erstellen und einen Pull Request starten.
editor.new_branch_name_desc=Neuer Branch Name...
editor.cancel=Abbrechen
editor.filename_cannot_be_empty=Der Dateiname darf nicht leer sein.
editor.branch_already_exists=Branch '%s' existiert bereits in diesem Repository.
editor.directory_is_a_file='%s' im übergeordneten Verzeichnis ist eine Datei und kein Verzeichnis.
editor.filename_is_a_directory=Die Datei '%s' existiert bereits als Verzeichnis in diesem Repository.
editor.file_editing_no_longer_exists=Die Datei '%s' welche Sie bearbeiten existiert in diesem Repository nicht mehr.
editor.file_changed_while_editing=Seit dem Start der Bearbeitung hat sich die Datei geändert. <a target="_blank" href="%s">Hier klicken</a> um die Änderungen zu sehen, oder nochmals <strong>Commit drücken</strong> um die Änderungen zu überschreiben.
editor.file_editing_no_longer_exists=Die Datei '%s', welche Sie bearbeiten, existiert in diesem Repository nicht mehr.
editor.file_changed_while_editing=Seit dem Start der Bearbeitung hat sich die Datei geändert. <a target="_blank" rel="noopener" href="%s">Hier klicken</a> um die Änderungen zu sehen, oder nochmals <strong>Commit drücken</strong> um die Änderungen zu überschreiben.
editor.file_already_exists=Eine Datei mit dem Namen '%s' existiert bereits in diesem Repository.
editor.no_changes_to_show=Keine Änderungen vorhanden.
editor.fail_to_update_file=Fehler beim Ändern/Erstellen der Datei '%s'. Fehler: %v
@@ -536,7 +537,7 @@ issues.commit_ref_at=`hat dieses Issue <a id="%[1]s" href="#%[1]s">%[2]s</a> aus
issues.poster=Ersteller
issues.collaborator=Mitarbeiter
issues.owner=Besitzer
issues.sign_in_require_desc=<a href="%s">Anmelden</a> um an der Diskussion teilzunehmen.
issues.sign_in_require_desc=<a href="%s">Anmelden</a>, um an der Diskussion teilzunehmen.
issues.edit=Bearbeiten
issues.cancel=Abbrechen
issues.save=Speichern
@@ -593,7 +594,7 @@ milestones.title=Titel
milestones.desc=Beschreibung
milestones.due_date=Fälligkeitsdatum (optional)
milestones.clear=Feld leeren
milestones.invalid_due_date_format=Format des Fälligkeitsdatums ist ungültig. Es muss das Format 'JJJJ-mm-dd' haben.
milestones.invalid_due_date_format=Format des Fälligkeitsdatums ist ungültig. Es muss das Format 'JJJJ-MM-TT' haben.
milestones.create_success=Meilenstein '%s' wurde erfolgreich erstellt!
milestones.edit=Meilenstein bearbeiten
milestones.edit_subheader=Verwenden Sie eine aussagekräftige Beschreibung für Meilensteine, um Missverständnisse zu vermeiden.
@@ -690,7 +691,7 @@ settings.search_user_placeholder=Benutzer suchen...
settings.org_not_allowed_to_be_collaborator=Eine Organisation kann nicht als Mitarbeiter hinzugefügt werden.
settings.user_is_org_member=Benutzer ist ein Organisationsmitglied und kann nicht als Mitarbeiter hinzugefügt werden.
settings.add_webhook=Webhook hinzufügen
settings.hooks_desc=Webhooks erlauben es Ihnen, externe Dienste zu informieren, wenn etwas Bestimmtes in Ihrem Repository passiert. Gitea sendet dann einen POST-Request an alle angegebenen URLs. Erfahren Sie mehr in unserem <a target="_blank" href="%s">Webhooks Guide</a>.
settings.hooks_desc=Webhooks erlauben es Ihnen, externe Dienste zu informieren, wenn etwas Bestimmtes in Ihrem Repository passiert. Gitea sendet dann einen POST-Request an alle angegebenen URLs. Erfahren Sie mehr in unserem <a target="_blank" rel="noopener" href="%s">Webhooks Guide</a>.
settings.webhook_deletion=Webhook entfernen
settings.webhook_deletion_desc=Das Löschen dieses Webhooks wird alle zugehörigen Informationen und den Übertragungsverlauf entfernen. Wirklich fortfahren?
settings.webhook_deletion_success=Webhook wurde erfolgreich entfernt!
@@ -707,7 +708,7 @@ settings.githook_edit_desc=Wenn ein Hook inaktiv ist, wird der Standardinhalt be
settings.githook_name=Hook-Name
settings.githook_content=Hook-Inhalt
settings.update_githook=Hook aktualisieren
settings.add_webhook_desc=Gitea sendet einen <code>POST</code>-Request an die unten stehende URL mit Details aller abonnierten Ereignisse. Sie können auch angeben, welches Datenformat Sie empfangen wollen (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). Mehr Informationen finden Sie im <a target="_blank" href="%s">Webhooks Guide</a>.
settings.add_webhook_desc=Gitea sendet einen <code>POST</code>-Request an die unten stehende URL mit Details aller abonnierten Ereignisse. Sie können auch angeben, welches Datenformat Sie empfangen wollen (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). Mehr Informationen finden Sie im <a target="_blank" rel="noopener" href="%s">Webhooks Guide</a>.
settings.payload_url=Payload URL
settings.content_type=Inhaltstyp
settings.secret=Secret
@@ -720,8 +721,8 @@ settings.event_send_everything=Ich brauche <strong>alles</strong>.
settings.event_choose=Lass mich auswählen, was ich brauche.
settings.event_create=Erstellen
settings.event_create_desc=Branch/Tag erstellt
settings.event_pull_request=Pull Request
settings.event_pull_request_desc=Pull-Request geöffnet, geschlossen, wieder geöffnet, bearbeitet, nicht zugewiesen, Label aktualisiert, Label gelöscht oder nicht synchronisiert.
settings.event_pull_request=Pull-Request
settings.event_pull_request_desc=Pull-Request geöffnet, geschlossen, wieder geöffnet, bearbeitet, zugewiesen, nicht zugewiesen, Label aktualisiert, Label gelöscht oder synchronisiert.
settings.event_push=Push
settings.event_push_desc=Git push auf ein Repository
settings.active=Aktiv
@@ -915,9 +916,9 @@ dashboard.current_goroutine=Aktuelle Goroutines
dashboard.current_memory_usage=Aktuelle Speichernutzung
dashboard.total_memory_allocated=Zugeteilter Gesamtspeicher
dashboard.memory_obtained=Erhaltener Speicher
dashboard.pointer_lookup_times=Pointer Lookup Times
dashboard.memory_allocate_times=Memory Allocate Times
dashboard.memory_free_times=Memory Free Times
dashboard.pointer_lookup_times=Anzahl Zeigerlookups
dashboard.memory_allocate_times=Anzahl Speicheranforderungen
dashboard.memory_free_times=Anzahl Speicherfreigaben
dashboard.current_heap_usage=Aktuelle Heap-Auslastung
dashboard.heap_memory_obtained=Erhaltener Heap-Memory
dashboard.heap_memory_idle=Unbenutzter Heap-Memory
@@ -938,7 +939,7 @@ dashboard.last_gc_time=Seit letztem GC-Zyklus
dashboard.total_gc_time=Gesamte GC-Pause
dashboard.total_gc_pause=Gesamte GC-Pause
dashboard.last_gc_pause=Letzte GC-Pause
dashboard.gc_times=GC-Takt
dashboard.gc_times=Anzahl GC
users.user_manage_panel=Benutzer
users.new_account=Neues Konto erstellen

View File

@@ -13,6 +13,7 @@ version = Version
page = Page
template = Template
language = Language
notifications = Notifications
create_new = Create...
user_profile_and_more = User profile and more
signed_in_as = Signed in as
@@ -47,7 +48,7 @@ cancel = Cancel
[install]
install = Installation
title = Install Steps For First-time Run
docker_helper = If you're running Gitea inside Docker, please read <a target="_blank" href="%s">Guidelines</a> carefully before you change anything in this page!
docker_helper = If you're running Gitea inside Docker, please read <a target="_blank" rel="noopener" href="%s">Guidelines</a> carefully before you change anything in this page!
requite_db_desc = Gitea requires MySQL, PostgreSQL, SQLite3 or TiDB.
db_title = Database Settings
db_type = Database Type
@@ -139,6 +140,9 @@ repos = Repositories
users = Users
organizations = Organizations
search = Search
repo_no_results = There are no matched repositories found.
user_no_results = There are no matched users found.
org_no_results = There are no matched organizations found.
[auth]
create_new_account = Create New Account
@@ -352,7 +356,7 @@ visibility = Visibility
visiblity_helper = This repository is <span class="ui red text">Private</span>
visiblity_helper_forced = Site admin has forced all new repositories to be <span class="ui red text">Private</span>
visiblity_fork_helper = (Change of this value will affect all forks)
clone_helper = Need help cloning? Visit <a target="_blank" href="%s">Help</a>!
clone_helper = Need help cloning? Visit <a target="_blank" rel="noopener" href="%s">Help</a>!
fork_repo = Fork Repository
fork_from = Fork From
fork_visiblity_helper = You cannot alter the visibility of a forked repository.
@@ -402,6 +406,7 @@ watch = Watch
unstar = Unstar
star = Star
fork = Fork
download_archive = Download this repository
no_desc = No Description
quick_guide = Quick Guide
@@ -458,7 +463,7 @@ editor.branch_already_exists = Branch '%s' already exists in this repository.
editor.directory_is_a_file = Entry '%s' in the parent path is a file not a directory in this repository.
editor.filename_is_a_directory = The filename '%s' is an existing directory in this repository.
editor.file_editing_no_longer_exists = The file '%s' you are editing no longer exists in the repository.
editor.file_changed_while_editing = File content has been changed since you started editing. <a target="_blank" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
editor.file_changed_while_editing = File content has been changed since you started editing. <a target="_blank" rel="noopener" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
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
@@ -492,7 +497,7 @@ issues.new_label = New Label
issues.new_label_placeholder = Label name...
issues.create_label = Create Label
issues.label_templates.title = Load a predefined set of labels
issues.label_templates.info = There arent any labels yet. You can click on the "New Label" button above to create one or use a predefined set below.
issues.label_templates.info = There aren't any labels yet. You can click on the "New Label" button above to create one or use a predefined set below.
issues.label_templates.helper = Select a label set
issues.label_templates.use = Use this label set
issues.label_templates.fail_to_load_file = Failed to load label template file '%s': %v
@@ -693,7 +698,7 @@ settings.search_user_placeholder = Search user...
settings.org_not_allowed_to_be_collaborator = Organization is not allowed to be added as a collaborator.
settings.user_is_org_member = User is organization member who cannot be added as a collaborator.
settings.add_webhook = Add Webhook
settings.hooks_desc = Webhooks are much like basic HTTP POST event triggers. Whenever something occurs in Gitea, we will handle the notification to the target host you specify. Learn more in this <a target="_blank" href="%s">Webhooks Guide</a>.
settings.hooks_desc = Webhooks are much like basic HTTP POST event triggers. Whenever something occurs in Gitea, we will handle the notification to the target host you specify. Learn more in this <a target="_blank" rel="noopener" href="%s">Webhooks Guide</a>.
settings.webhook_deletion = Delete Webhook
settings.webhook_deletion_desc = Delete this webhook will remove its information and all delivery history. Do you want to continue?
settings.webhook_deletion_success = Webhook has been deleted successfully!
@@ -710,7 +715,7 @@ settings.githook_edit_desc = If the hook is inactive, sample content will be pre
settings.githook_name = Hook Name
settings.githook_content = Hook Content
settings.update_githook = Update Hook
settings.add_webhook_desc = Gitea will send a <code>POST</code> request to the URL you specify, along with regarding the event that occured. You can also specify what kind of data format you'd like to get upon triggering the hook (JSON, x-www-form-urlencoded, XML, etc). More information can be found in our <a target="_blank" href="%s">Webhooks Guide</a>.
settings.add_webhook_desc = Gitea will send a <code>POST</code> request to the URL you specify, along with regarding the event that occured. You can also specify what kind of data format you'd like to get upon triggering the hook (JSON, x-www-form-urlencoded, XML, etc). More information can be found in our <a target="_blank" rel="noopener" href="%s">Webhooks Guide</a>.
settings.payload_url = Payload URL
settings.content_type = Content Type
settings.secret = Secret
@@ -1173,7 +1178,7 @@ close_pull_request = `closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request = `reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue = `commented on issue <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request = `merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo = transfered repository <code>%s</code> to <a href="%s">%s</a>
transfer_repo = transferred repository <code>%s</code> to <a href="%s">%s</a>
push_tag = pushed tag <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a>
compare_commits = View comparison for these %d commits
@@ -1203,3 +1208,10 @@ default_message = Drop files here or click to upload.
invalid_input_type = You can't upload files of this type.
file_too_big = File size ({{filesize}} MB) exceeds maximum size ({{maxFilesize}} MB).
remove_file = Remove file
[notification]
notifications = Notifications
unread = Unread
read = Read
no_unread = You have no unread notifications.
no_read = You have no read notifications.

View File

@@ -25,7 +25,7 @@ captcha=Captcha
repository=Repositorio
organization=Organización
mirror=Mirror
mirror=Réplica
new_repo=Nuevo repositorio
new_migrate=Nueva migración
new_mirror=Nueva réplica
@@ -47,7 +47,7 @@ cancel=Cancelar
[install]
install=Instalación
title=Pasos de la instalación por primera vez
docker_helper=Si está ejecutando Gitea usando Docker, ¡por favor lea <a target="_blank" href="%s"> estas pautas</a> antes de cambiar nada en esta página!
docker_helper=Si está ejecutando Gitea usando Docker, ¡por favor lea <a target="_blank" rel="noopener" href="%s"> estas pautas</a> antes de cambiar nada en esta página!
requite_db_desc=Gitea requiere una base de datos MySQL, PostgreSQL, SQLite3 o TiDB.
db_title=Configuración de base de datos
db_type=Tipo de base de datos
@@ -190,11 +190,11 @@ AuthName=Nombre de autorización
AdminEmail=Correo electrónico del administrador
NewBranchName=Nuevo nombre de rama
CommitSummary=Commit summary
CommitMessage=Commit message
CommitChoice=Commit choice
TreeName=File path
Content=Content
CommitSummary=Resumen del commit
CommitMessage=Mensaje de commit
CommitChoice=Hacer commit de la elección
TreeName=Ruta del archivo
Content=Contenido
require_error=` no puede estar vacío.`
alpha_dash_error=` los caracteres deben ser Alfanumericos o dash(-_).`
@@ -351,7 +351,7 @@ visibility=Visibilidad
visiblity_helper=Este repositorio es <span class="ui red text">privado</span>
visiblity_helper_forced=El administrador web ha obligado a todos los repositorios nuevos a ser <span class="ui red text"> privados</span>
visiblity_fork_helper=(Este cambio afectará a todos los forks)
clone_helper=¿Necesitas ayuda con el clone? ¡Consulta la <a target="_blank" href="%s">Ayuda</a>!
clone_helper=¿Necesitas ayuda con el clone? ¡Consulta la <a target="_blank" rel="noopener" href="%s">Ayuda</a>!
fork_repo=Hacer Fork del repositorio
fork_from=Crear un Fork desde
fork_visiblity_helper=No es posible cambiar la visibilidad de un Fork
@@ -370,7 +370,7 @@ mirror_prune_desc=Remover referencias remotas que no existan remotamente
mirror_interval=Intervalo de la réplica (en horas)
mirror_address=Dirección de la réplica
mirror_address_desc=Por favor, incluya las credenciales de usuario necesarias en la dirección.
mirror_last_synced=Last Synced
mirror_last_synced=Última sincronización
watchers=Seguidores
stargazers=Fans
forks=Forks
@@ -401,6 +401,7 @@ watch=Seguir
unstar=Eliminar destacado
star=Destacar
fork=Fork
download_archive=Descargar este repositorio
no_desc=Sin descripción
quick_guide=Guía Rápida
@@ -428,45 +429,45 @@ file_permalink=Permalink
file_too_large=Este archivo es demasiado grande para ser mostrado
editor.new_file=Nuevo archivo
editor.upload_file=Upload file
editor.edit_file=Edit file
editor.preview_changes=Preview Changes
editor.cannot_edit_non_text_files=Cannot edit non-text files
editor.edit_this_file=Edit this file
editor.must_be_on_a_branch=You must be on a branch to make or propose changes to this file
editor.fork_before_edit=You must fork this repository before editing the file
editor.delete_this_file=Delete this file
editor.must_have_write_access=You must have write access to make or propose changes to this file
editor.file_delete_success=File '%s' has been deleted successfully!
editor.name_your_file=Name your file...
editor.filename_help=To add directory, just type it and press /. To remove a directory, go to the beginning of the field and press backspace.
editor.or=or
editor.cancel_lower=cancel
editor.commit_changes=Commit Changes
editor.add_tmpl=Add '%s/<filename>'
editor.add=Add '%s'
editor.update=Update '%s'
editor.delete=Delete '%s'
editor.commit_message_desc=Add an optional extended description...
editor.commit_directly_to_this_branch=Commit directly to the <strong class="branch-name">%s</strong> branch.
editor.create_new_branch=Create a <strong>new branch</strong> for this commit and start a pull request.
editor.new_branch_name_desc=New branch name...
editor.cancel=Cancel
editor.filename_cannot_be_empty=Filename cannot be empty.
editor.branch_already_exists=Branch '%s' already exists in this repository.
editor.directory_is_a_file=Entry '%s' in the parent path is a file not a directory in this repository.
editor.filename_is_a_directory=The filename '%s' is an existing directory in this repository.
editor.file_editing_no_longer_exists=The file '%s' you are editing no longer exists in the repository.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
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.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'
editor.upload_file=Subir archivo
editor.edit_file=Editar archivo
editor.preview_changes=Vista previa de los cambios
editor.cannot_edit_non_text_files=Sólo puede editar archivos de texto
editor.edit_this_file=Editar este archivo
editor.must_be_on_a_branch=Debes estar en una rama para hacer o proponer cambios en este archivo
editor.fork_before_edit=Debes hacer un fork de este repositorio antes de editar el archivo
editor.delete_this_file=Eliminar este archivo
editor.must_have_write_access=Debes tener permisos de escritura para hacer o proponer cambios a este archivo
editor.file_delete_success=¡El archivo '%s' ha sido eliminado con éxito!
editor.name_your_file=Nombre de archivo...
editor.filename_help=Para añadir un directorio, simplemente escribelo y presiona /. Para eliminar un directorio, ve al principio del campo y presiona retroceso.
editor.or=o
editor.cancel_lower=cancelar
editor.commit_changes=Hacer commit de los cambios
editor.add_tmpl=Añadir '%s<filename>'
editor.add=Añadir '%s'
editor.update=Actualizar '%s'
editor.delete=Eliminar '%s'
editor.commit_message_desc=Añadir una descripción extendida opcional...
editor.commit_directly_to_this_branch=Hacer commit directamente en la rama <strong class="branch-name">%s</strong>.
editor.create_new_branch=Crear una <strong>nueva rama</strong> para este commit y hacer un pull request.
editor.new_branch_name_desc=Nombre de la rama nueva...
editor.cancel=Cancelar
editor.filename_cannot_be_empty=El nombre del archivo no puede estar vacío.
editor.branch_already_exists=La rama '%s' ya existe en este repositorio.
editor.directory_is_a_file=La entrada '%s' en el directorio padre es un archivo no un directorio en este repositorio.
editor.filename_is_a_directory=El nombre del fichero '%s' es un directorio existente en este repositorio.
editor.file_editing_no_longer_exists=El archivo '%s' que estás editando ya no existe en este repositorio.
editor.file_changed_while_editing=El contenido del archivo ha sido modificado desde que empezó a editarlo. <a target="_blank" rel="noopener" href="%s">Clic aquí</a> para ver qué ha sido modificado o <strong>presiona confirmar de nuevo</strong> para sobrescribir estos cambios.
editor.file_already_exists=Ya existe un archivo con nombre '%s' en este repositorio.
editor.no_changes_to_show=No existen cambios para mostrar.
editor.fail_to_update_file=Error al actualizar/crear el archivo '%s', error: %v
editor.add_subdir=Añadir subdirectorio...
editor.unable_to_upload_files=Error al subir archivos a '%s', error: %v
editor.upload_files_to_dir=Subir archivos a '%s'
commits.commits=Commits
commits.search=Buscar Commits
commits.search=Buscar commits
commits.find=Buscar
commits.author=Autor
commits.message=Mensaje
@@ -490,11 +491,11 @@ issues.create=Crear incidencia
issues.new_label=Nueva Etiqueta
issues.new_label_placeholder=Nombre etiqueta...
issues.create_label=Crear etiqueta
issues.label_templates.title=Load a predefined set of labels
issues.label_templates.info=There arent any labels yet. You can click on the "New Label" button above to create one or use a predefined set below.
issues.label_templates.helper=Select a label set
issues.label_templates.use=Use this label set
issues.label_templates.fail_to_load_file=Failed to load label template file '%s': %v
issues.label_templates.title=Carga un conjunto predefinido de etiquetas
issues.label_templates.info=Todavía no hay ninguna etiqueta. Puede hacer clic en el botón "Nueva etiqueta" para crear una o utilizar un conjunto predefinido abajo.
issues.label_templates.helper=Seleccionar un conjunto de etiquetas
issues.label_templates.use=Usar este conjunto de etiquetas
issues.label_templates.fail_to_load_file=Error al cargar el archivo de plantilla de etiqueta '%s': %v
issues.open_tab=%d abiertas
issues.close_tab=%d cerradas
issues.filter_label=Etiqueta
@@ -522,7 +523,7 @@ issues.next=Página Siguiente
issues.open_title=Abierta
issues.closed_title=Cerrada
issues.num_comments=%d comentarios
issues.commented_at='comentado <a href="#%s"> %s'</a>
issues.commented_at=`comentado <a href="#%s"> %s`</a>
issues.delete_comment_confirm=¿Seguro que deseas eliminar este comentario?
issues.no_content=Aún no existe contenido.
issues.close_issue=Cerrar
@@ -536,7 +537,7 @@ issues.commit_ref_at=`mencionada esta incidencia en un commit <a id="%[1]s" href
issues.poster=Autor
issues.collaborator=Colaborador
issues.owner=Propietario
issues.sign_in_require_desc=<a href="%s">Sign in</a> to join this conversation.
issues.sign_in_require_desc=<a href="%s"> Inicie sesión</a> para unirse a esta conversación.
issues.edit=Editar
issues.cancel=Cancelar
issues.save=Guardar
@@ -551,8 +552,8 @@ issues.label_deletion=Borrado de Etiqueta
issues.label_deletion_desc=Al borrar la etiqueta su información será eliminada de todas las incidencias relacionadas. Desea continuar?
issues.label_deletion_success=Etiqueta borrada con éxito!
issues.num_participants=%d participantes
issues.attachment.open_tab=`Click to see "%s" in a new tab`
issues.attachment.download=`Click to download "%s"`
issues.attachment.open_tab='Haga clic para ver "%s" en una pestaña nueva'
issues.attachment.download=`Haga clic para descargar "%s"`
pulls.new=Nuevo Pull Request
pulls.compare_changes=Comparar cambios
@@ -570,8 +571,8 @@ pulls.tab_conversation=Conversación
pulls.tab_commits=Commits
pulls.tab_files=Archivos modificados
pulls.reopen_to_merge=Por favor reabra este Pull Request para proceder con la operación de fusionado.
pulls.merged=Fuisionado
pulls.has_merged=¡Este pull request se ha completado con éxito!
pulls.merged=Fusionado
pulls.has_merged=¡Este Pull Request se ha completado con éxito!
pulls.data_broken=Los datos de este pull request ya no están disponibles porque se ha eliminado la información del fork.
pulls.is_checking=Se está procediendo a la búsqueda de conflictos, por favor actualice la página en unos momentos.
pulls.can_auto_merge_desc=Este Pull Request puede ser fusionado automáticamente.
@@ -632,9 +633,9 @@ settings.collaboration.undefined=Indefinido
settings.hooks=Webhooks
settings.githooks=Git Hooks
settings.basic_settings=Configuración Básica
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=Configuración de réplica
settings.sync_mirror=Sincronizar ahora
settings.mirror_sync_in_progress=Sincronización de réplica en curso, por favor actualice la página en unos minutos.
settings.site=Sitio oficial
settings.update_settings=Actualizar configuración
settings.change_reponame_prompt=Este cambio afectará a los enlaces al repositorio.
@@ -690,7 +691,7 @@ settings.search_user_placeholder=Buscar usuario...
settings.org_not_allowed_to_be_collaborator=Las organizaciones no tiene permitido ser añadidas como colaboradores.
settings.user_is_org_member=El usuario es miembro de la organización, no puede ser añadido como colaborador.
settings.add_webhook=Añadir Webhook
settings.hooks_desc=Los Webhooks permiten a servicios externos recibir notificaciones cuando sucedan ciertos eventos en Gitea. Cuando sucedan los eventos especificados, enviaremos una petición POST a cada una de las URLs indicadas. Para obtener más información, consulta nuestra <a target="_blank" href="%s">Guía de Webhooks</a>.
settings.hooks_desc=Los Webhooks permiten a servicios externos recibir notificaciones cuando sucedan ciertos eventos en Gitea. Cuando sucedan los eventos especificados, enviaremos una petición POST a cada una de las URLs indicadas. Para obtener más información, consulta nuestra <a target="_blank" rel="noopener" href="%s">Guía de Webhooks</a>.
settings.webhook_deletion=Eliminar Webhook
settings.webhook_deletion_desc=Al borrar este webhook se eliminará su información y todo su historial. ¿Desea continuar?
settings.webhook_deletion_success=¡Webhook eliminado con éxito!
@@ -707,7 +708,7 @@ settings.githook_edit_desc=Si el hook no está activo, se mostrará contenido de
settings.githook_name=Nombre del Hook
settings.githook_content=Contenido del Hook
settings.update_githook=Actualizar Hook
settings.add_webhook_desc=Enviaremos una petición <code>POST</code> a la siguiente URL con los detalles de cualquier evento suscrito. También puedes especificar qué formato de datos te gustaría recibir (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). Puedes encontrar más información en la <a target="_blank" href="%s">Guía de Webhooks</a>.
settings.add_webhook_desc=Enviaremos una petición <code>POST</code> a la siguiente URL con los detalles de cualquier evento suscrito. También puedes especificar qué formato de datos te gustaría recibir (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). Puedes encontrar más información en la <a target="_blank" rel="noopener" href="%s">Guía de Webhooks</a>.
settings.payload_url=URL de Payload
settings.content_type=Tipo de contenido
settings.secret=Secreto
@@ -721,7 +722,7 @@ settings.event_choose=Déjeme elegir lo que necesito.
settings.event_create=Crear
settings.event_create_desc=Rama o etiqueta creada
settings.event_pull_request=Pull Request
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, or synchronized.
settings.event_pull_request_desc=Pull request, abierta, cerrada, reabierta, editada, asignada, desasignada, con etiqueta actualizada, con etiqueta eliminada, o sincronizada.
settings.event_push=Push
settings.event_push_desc=Git push a un repositorio
settings.active=Activo
@@ -1122,7 +1123,7 @@ config.git_max_diff_line_characters=Carácteres de Diff máximos (para una sola
config.git_max_diff_files=Máximo de archivos de Diff (que se mostrarán)
config.git_gc_args=Argumentos de GC
config.git_migrate_timeout=Tiempo de espera de migración
config.git_mirror_timeout=Tiempo de espera de actualización de espejos
config.git_mirror_timeout=Tiempo de espera de actualización de réplicas
config.git_clone_timeout=Tiempo de espera de operación de clones
config.git_pull_timeout=Tiempo de espera de operación de pull
config.git_gc_timeout=Tiempo de espera de operación de GC
@@ -1188,7 +1189,7 @@ hours=%[2]s %[1]d horas
days=%[2]s %[1]d días
weeks=%[2]s %[1]d semanas
months=%[2]s %[1]d meses
years=%s %d años
years=%[2]s %[1]d años
raw_seconds=segundos
raw_minutes=minutos

View File

@@ -47,7 +47,7 @@ cancel=Peruuta
[install]
install=Asennus
title=Asennusvaiheet ottaessa ensi kertaa käyttöön
docker_helper=Jos käytät Giteaia Dockerin sisällä, ole hyvä ja lue <a target="_blank" href="%s">ohjeet</a> huolellisesti ennen kuin muutat mitään tältä sivulta!
docker_helper=Jos käytät Giteaia Dockerin sisällä, ole hyvä ja lue <a target="_blank" rel="noopener" href="%s">ohjeet</a> huolellisesti ennen kuin muutat mitään tältä sivulta!
requite_db_desc=Gitea tarvitsee MySQL, PostgreSQL, SQLite3 tai TiDB.
db_title=Tietokanta asetukset
db_type=Tietokanta tyyppi
@@ -351,7 +351,7 @@ visibility=Näkyvyys
visiblity_helper=Tämä repo on <span class="ui red text">yksityinen</span>
visiblity_helper_forced=Sivuston ylläpito on pakottanut kaikkien uusien repojen olevan <span class="ui red text">yksityisiä</span>
visiblity_fork_helper=(Arvon vaihtaminen vaikuttaa kaikkiin forkkeihin)
clone_helper=Tarvitsetko apua kloonauksessa? Vieraile osoitteessa <a target="_blank" href="%s">Apua</a>!
clone_helper=Tarvitsetko apua kloonauksessa? Vieraile osoitteessa <a target="_blank" rel="noopener" href="%s">Apua</a>!
fork_repo=Forkkaa repo
fork_from=Forkkaa lähteestä
fork_visiblity_helper=Et voi muuttaa forkatun repon näkyvyyttä.
@@ -457,7 +457,7 @@ editor.branch_already_exists=Branch '%s' already exists in this repository.
editor.directory_is_a_file=Entry '%s' in the parent path is a file not a directory in this repository.
editor.filename_is_a_directory=The filename '%s' is an existing directory in this repository.
editor.file_editing_no_longer_exists=The file '%s' you are editing no longer exists in the repository.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" rel="noopener" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
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
@@ -690,7 +690,7 @@ settings.search_user_placeholder=Etsi käyttäjä...
settings.org_not_allowed_to_be_collaborator=Yhteistyökumppaniksi ei voi lisätä organisaatiota.
settings.user_is_org_member=Käyttäjä on organisaation jäsen, jota ei voi lisätä yhteistyökumppaniksi.
settings.add_webhook=Lisää webkoukku
settings.hooks_desc=Webkoukut muistuttavat paljon perus HTTP POST tapahtuma laukaisimia. Aina kun jotain tapahtuu Giteaissa, käsittelemme ilmoituksen määrittäämääsi kohteeseen. Lisätietoja <a target="_blank" href="%s">webkoukku oppaassa</a>.
settings.hooks_desc=Webkoukut muistuttavat paljon perus HTTP POST tapahtuma laukaisimia. Aina kun jotain tapahtuu Giteaissa, käsittelemme ilmoituksen määrittäämääsi kohteeseen. Lisätietoja <a target="_blank" rel="noopener" href="%s">webkoukku oppaassa</a>.
settings.webhook_deletion=Poista webkoukku
settings.webhook_deletion_desc=Tämän webkoukun poistaminen poistaa sen tiedot ja kaiken toimitushistorian. Haluatko jatkaa?
settings.webhook_deletion_success=Webkoukku on poistettu onnistuneesti!
@@ -707,7 +707,7 @@ settings.githook_edit_desc=Jos koukku ei ole käytössä, esitellään esimerkki
settings.githook_name=Koukun nimi
settings.githook_content=Koukun sisältö
settings.update_githook=Päivitys koukku
settings.add_webhook_desc=Gitea lähettää <code>POST</code> requestin määrittämääsi URLiin, mukaanlukien tapahtuneen eventin. Voit myös määrittää millaisen tiedostomuodon haluat saada koukun lauettua (JSON, x-www-form-urlencoded, XML, jne). Lisätietoa löytyy meidän <a target="_blank" href="%s">koukut oppaasta</a>.
settings.add_webhook_desc=Gitea lähettää <code>POST</code> requestin määrittämääsi URLiin, mukaanlukien tapahtuneen eventin. Voit myös määrittää millaisen tiedostomuodon haluat saada koukun lauettua (JSON, x-www-form-urlencoded, XML, jne). Lisätietoa löytyy meidän <a target="_blank" rel="noopener" href="%s">koukut oppaasta</a>.
settings.payload_url=Payload URL
settings.content_type=Sisältötyyppi
settings.secret=Salaus

View File

@@ -47,7 +47,7 @@ cancel=Annuler
[install]
install=Installation
title=Instructions pour la première exécution
docker_helper=Si vous exécutez Gitea grâce à Docker, merci de lire la <a target="_blank" href="%s">procédure</a> attentivement avant de modifier quoi que ce soit sur cette page !
docker_helper=Si vous exécutez Gitea grâce à Docker, merci de lire la <a target="_blank" rel="noopener" href="%s">procédure</a> attentivement avant de modifier quoi que ce soit sur cette page !
requite_db_desc=Gitea requiert MySQL, PostgreSQL, SQLite3 ou TiDB.
db_title=Paramètres de la base de données
db_type=Type de base de données
@@ -115,16 +115,16 @@ test_git_failed=Le test de la commande "git" a échoué : %v
sqlite3_not_available=Votre version publiée ne prend pas en charge SQLite3. Veuillez télécharger la version binaire officielle à cette adresse %s.
invalid_db_setting=Paramètres de base de données incorrects : %v
invalid_repo_path=Chemin vers la racine du dépôt invalide : %v
run_user_not_match=L'utilisateur entré n'est pas l'utilisateur actuel : %s -> %s
run_user_not_match=L'utilisateur d'exécution saisi n'est pas l'utilisateur d'exécution actuel : %s -> %s
save_config_failed=La sauvegarde de la configuration a échoué : %v
invalid_admin_setting=Paramètres du compte administrateur invalides : %v
install_success=Bienvenue ! Nous sommes heureux que vous ayez choisi Gitea, amusez-vous et prenez soin de vous.
invalid_log_root_path=Le chemin principal des fichiers logs est invalide: %v
invalid_log_root_path=L'emplacement racine des fichiers logs est invalide : %v
[home]
uname_holder=Nom d'utilisateur ou e-mail
password_holder=Mot de passe
switch_dashboard_context=Basculer le Contexte du Tableau de Bord
switch_dashboard_context=Basculer le contexte du tableau de bord
my_repos=Mes dépôts
show_more_repos=Afficher plus de dépôts...
collaborative_repos=Dépôts collaboratifs
@@ -144,7 +144,7 @@ create_new_account=Créer un nouveau compte
register_hepler_msg=Déjà enregistré ? Connectez-vous !
social_register_hepler_msg=Déjà enregistré ? Associez-le !
disable_register_prompt=Désolé, les enregistrements ont été désactivés. Veuillez contacter l'administrateur du site.
disable_register_mail=Désolé, la Confirmation par Mail des Enregistrements a été désactivée.
disable_register_mail=Désolé, la confirmation par e-mail des enregistrements a été désactivée.
remember_me=Se souvenir de moi
forgot_password=Mot de passe oublié
forget_password=Mot de passe oublié ?
@@ -162,13 +162,13 @@ reset_password=Réinitialiser le mot de passe
invalid_code=Désolé, votre code de confirmation est invalide ou a expiré.
reset_password_helper=Cliquez ici pour réinitialiser votre mot de passe
password_too_short=Le mot de passe doit contenir 6 caractères minimum.
non_local_account=Les comptes non-locaux ne peuvent pas changer leur mot de passe via Gitea.
non_local_account=Les comptes non locaux ne peuvent pas changer leur mot de passe via Gitea.
[mail]
activate_account=Veuillez activer votre compte
activate_email=Veuillez vérifier votre adresse e-mail
reset_password=Réinitialiser votre mot de passe
register_success=Succès de l'enregistrement, Bienvenue
register_success=Inscription réussie, bienvenue
register_notify=Bienvenue à bord
[modal]
@@ -179,13 +179,13 @@ modify=Modifier
[form]
UserName=Nom d'utilisateur
RepoName=Nom du dépôt
Email=Adresse E-mail
Email=Adresse e-mail
Password=Mot de passe
Retype=Confirmez le mot de passe
SSHTitle=Nom de la clé SSH
HttpsUrl=URL HTTPS
PayloadUrl=URL des Données Utiles
TeamName=Nom d'équipe
PayloadUrl=URL des données utiles
TeamName=Nom de l'équipe
AuthName=Nom d'autorisation
AdminEmail=E-mail de l'administrateur
@@ -196,9 +196,9 @@ CommitChoice=Choix de commit
TreeName=Chemin du fichier
Content=Contenu
require_error=` Ne peut être vide `
alpha_dash_error=` doivent être des caractères alpha, numeriques ou console (-_) valides `
alpha_dash_dot_error=` doivent être des caractères alpha, numeriques, console (-_) valides ou des points `
require_error=` ne peut pas être vide.`
alpha_dash_error=` doivent être des caractères alpha, numériques ou tirets (-_) valides.`
alpha_dash_dot_error=` doivent être des caractères alpha, numériques, tirets (-_) valides ou des points.`
size_error=` doit être à la taille de %s.`
min_size_error=` %s caractères minimum `
max_size_error=` %s caractères maximum `
@@ -351,7 +351,7 @@ visibility=Visibilité
visiblity_helper=Ce dépôt est <span class="ui red text"> privé</span>
visiblity_helper_forced=L'administrateur du site a forcé tous les nouveaux dépôts à être <span class="ui red text">privés</span>
visiblity_fork_helper=(Les changement de cette valeur affecteront tous les forks)
clone_helper=Besoin d'aide pour dupliquer ? Visitez <a target="_blank" href="%s">l'aide</a> !
clone_helper=Besoin d'aide pour dupliquer ? Visitez <a target="_blank" rel="noopener" href="%s">l'aide</a> !
fork_repo=Créer un fork du dépôt
fork_from=Fork de
fork_visiblity_helper=La visibilité d'un fork ne peut pas être modifiée.
@@ -457,7 +457,7 @@ editor.branch_already_exists=La branche '%s' existe déjà dans ce dépôt.
editor.directory_is_a_file=L'entrée '%s' dans le chemin daccès parent est un fichier pas un répertoire dans ce dépôt.
editor.filename_is_a_directory=Le nom de fichier '%s' existe déjà dans ce dépot.
editor.file_editing_no_longer_exists=Le fichier '%s' que vous modifiez n'existe plus dans le dépôt.
editor.file_changed_while_editing=Le contenu du fichier à changé depuis que vous avez commencé à l'éditer. <a target="_blank" href="%s">Cliquez ici</a> pour voir ce qui à été modifié ou <strong>appuyez sur commit encore une fois</strong> pour remplacer ces changements.
editor.file_changed_while_editing=Le contenu du fichier à changé depuis que vous avez commencé à l'éditer. <a target="_blank" rel="noopener" href="%s">Cliquez ici</a> pour voir ce qui à été modifié ou <strong>appuyez sur commit encore une fois</strong> pour remplacer ces changements.
editor.file_already_exists=La branche '%s' existe déjà dans ce dépôt.
editor.no_changes_to_show=Il ny a aucun changement à afficher.
editor.fail_to_update_file=Échec lors de la mise à jour/création du fichier '%s' avec lerreur : %v
@@ -690,7 +690,7 @@ settings.search_user_placeholder=Rechercher un utilisateur...
settings.org_not_allowed_to_be_collaborator=Une organisation n'est pas autorisée à être ajoutée en tant que collaborateur.
settings.user_is_org_member=Cet utilisateur ne peut pas être ajouté en tant que collaborateur car il fait partie d'une organisation.
settings.add_webhook=Ajouter un Webhook
settings.hooks_desc=Les Webhooks sont des déclencheurs de POST HTTP . Lorsque qu'un événement se produit dans Gitea, une notification sera envoyée vers l'hôte cible préalablement spécifié. Apprenez-en davantage dans le <a target="_blank" href="%s">Guide des Webhooks</a>.
settings.hooks_desc=Les Webhooks sont des déclencheurs de POST HTTP . Lorsque qu'un événement se produit dans Gitea, une notification sera envoyée vers l'hôte cible préalablement spécifié. Apprenez-en davantage dans le <a target="_blank" rel="noopener" href="%s">Guide des Webhooks</a>.
settings.webhook_deletion=Supprimer le Webhook
settings.webhook_deletion_desc=Supprimer ce webhook va supprimer ses informations et l'historique de livraison. Voulez-vous continuer ?
settings.webhook_deletion_success=Le webhook a été supprimé avec succès !
@@ -699,7 +699,7 @@ settings.webhook.test_delivery_desc=Envoyer un faux push pour tester la configur
settings.webhook.test_delivery_success=Le webhook de test a été ajouté à la file d'attente de livraison. L'affichage dans l'historique de livraison peut prendre quelques secondes.
settings.webhook.request=Requête
settings.webhook.response=Réponse
settings.webhook.headers=Entêtes 
settings.webhook.headers=Entêtes
settings.webhook.payload=Payload
settings.webhook.body=Corps
settings.githooks_desc=Les Hooks Git sont alimentés par Git lui même. Les Hooks compatibles sont modifiables dans la liste ci-dessous pour effectuer des opérations personnalisées.
@@ -707,7 +707,7 @@ settings.githook_edit_desc=Si un Hook est inactif, un exemple de contenu vous se
settings.githook_name=Nom du Hook
settings.githook_content=Contenu du Hook
settings.update_githook=Mettre le Hook à jour
settings.add_webhook_desc=Une requête <code>POST</code> sera transmise vers l'URL spécifiée selon l'événement produit. Vous pouvez également choisir le format souhaité pour la réception des données (JSON, x-www-form-urlencoded, XML etc). Pour plus d'infos, lisez le <a target="_blank" href="%s">Guide des WebHooks</a>.
settings.add_webhook_desc=Une requête <code>POST</code> sera transmise vers l'URL spécifiée selon l'événement produit. Vous pouvez également choisir le format souhaité pour la réception des données (JSON, x-www-form-urlencoded, XML etc). Pour plus d'infos, lisez le <a target="_blank" rel="noopener" href="%s">Guide des WebHooks</a>.
settings.payload_url=URL des Données Utiles
settings.content_type=Type de contenu
settings.secret=Confidentiel
@@ -773,7 +773,7 @@ release.source_code=Code source
release.new_subheader=Publier une version pour itérer sur le produit.
release.edit_subheader=Un changelog détaillé peut aider les utilisateurs à comprendre ce qui a été amélioré.
release.tag_name=Nom du tag
release.target=Cible 
release.target=Cible
release.tag_helper=Choisissez un tag existant ou créez-en un nouveau à publier.
release.title=Titre
release.content=Contenu

View File

@@ -47,7 +47,7 @@ cancel=Annulla
[install]
install=Installazione
title=Passi d'installazione per il primo avvio
docker_helper=Se stai utilizzando Gitea su Docker, per favore leggi le <a target="_blank" href="%s">Linee guida</a> con attenzione prima di cambiare qualcosa su questa pagina!
docker_helper=Se stai utilizzando Gitea su Docker, per favore leggi le <a target="_blank" rel="noopener" href="%s">Linee guida</a> con attenzione prima di cambiare qualcosa su questa pagina!
requite_db_desc=Gitea necessita MySQL, PostgreSQL, SQLite3 o TiDB.
db_title=Impostazioni Database
db_type=Tipo di database
@@ -126,7 +126,7 @@ uname_holder=Nome Utente o E-mail
password_holder=Password
switch_dashboard_context=Cambia Dashboard Context
my_repos=I miei Repository
show_more_repos=Show more repositories...
show_more_repos=Visualizza altre repositories...
collaborative_repos=Repository Condivisi
my_orgs=Le mie Organizzazioni
my_mirrors=I miei Mirror
@@ -151,8 +151,8 @@ forget_password=Password dimenticata?
sign_up_now=Bisogno di un account? Iscriviti ora.
confirmation_mail_sent_prompt=Una nuova email di conferma è stata inviata a <b>%s</b>, verifica la tua casella di posta entro le prossime %d ore per completare la registrazione.
active_your_account=Attiva il tuo Account
prohibit_login=Login Prohibited
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
prohibit_login=Accesso Vietato
prohibit_login_desc=Il tuo account è impossibilitato al login, contatta l'amministratore del sito.
resent_limit_prompt=Siamo spiacenti, si stanno inviando e-mail di attivazione troppo spesso. Si prega di attendere 3 minuti.
has_unconfirmed_mail=Ciao %s, hai un indirizzo di posta elettronica non confermato (<b>%s</b>). Se non hai ricevuto una e-mail di conferma o vuoi riceverla nuovamente, fare clic sul pulsante qui sotto.
resend_mail=Clicca qui per inviare nuovamente l'e-mail di attivazione
@@ -162,7 +162,7 @@ reset_password=Reimposta la tua Password
invalid_code=Siamo spiacenti, il codice di conferma è scaduto o non valido.
reset_password_helper=Clicca qui per reimpostare la password
password_too_short=La lunghezza della password non può essere meno 6 caratteri.
non_local_account=Non-local accounts cannot change passwords through Gitea.
non_local_account=Gli account non locali non possono modificare le password tramite Gitea.
[mail]
activate_account=Per favore attiva il tuo account
@@ -189,12 +189,12 @@ TeamName=Nome Team
AuthName=Nome autorizzazione
AdminEmail=Email dell'Admin
NewBranchName=New branch name
CommitSummary=Commit summary
CommitMessage=Commit message
CommitChoice=Commit choice
TreeName=File path
Content=Content
NewBranchName=Nuovo nome del branch
CommitSummary=Riepilogo dei commit
CommitMessage=Messaggio di commit
CommitChoice=Scelta di commit
TreeName=Percorso del file
Content=Contenuto
require_error=` non può essere vuoto.`
alpha_dash_error=` ammessi solo caratteri alfanumerici o trattini(-_).`
@@ -232,7 +232,7 @@ org_still_own_repo=Questa organizzazione ha ancora la proprietà del repository,
target_branch_not_exist=Il ramo (branch) di destinazione non esiste.
[user]
change_avatar=Change your avatar
change_avatar=Cambia il tuo avatar
join_on=Si è unito il
repositories=Repository
activity=Attività pubblica
@@ -269,7 +269,7 @@ change_username_prompt=Questa modifica influenzerà il modo in cui i link si rif
continue=Continua
cancel=Annulla
lookup_avatar_by_mail=Lookup Avatar by mail
lookup_avatar_by_mail=Ricerca Avatar per mail
federated_avatar_lookup=Federated Avatar Lookup
enable_custom_avatar=Abilita avatar personalizzato
choose_new_avatar=Scegli un nuovo avatar
@@ -351,13 +351,13 @@ visibility=Visibilità
visiblity_helper=Questo repository è <span class="ui red text"> privato</span>
visiblity_helper_forced=L'amministratore del sito ha deciso che tutti i nuovi repository devono essere <span class="ui red text">privati</span>
visiblity_fork_helper=(La modifica di questo valore avrà effetto su tutti i fork)
clone_helper=Hai bisogno di aiuto per la clonazione? Visita <a target="_blank" href="%s">Aiuto</a>!
clone_helper=Hai bisogno di aiuto per la clonazione? Visita <a target="_blank" rel="noopener" href="%s">Aiuto</a>!
fork_repo=Forka Repository
fork_from=Forka da
fork_visiblity_helper=Non puoi cambiare la visibilità di un repository forkato.
repo_desc=Descrizione
repo_lang=Lingua
repo_gitignore_helper=Select .gitignore templates
repo_gitignore_helper=Seleziona i templates di .gitignore
license=Licenza
license_helper=Selezionare un file di licenza
readme=Readme
@@ -365,7 +365,7 @@ readme_helper=Seleziona un template per il readme
auto_init=Inizializzare questo repository con i file e il modello selezionati
create_repo=Crea Repository
default_branch=Ramo (Branch) predefinito
mirror_prune=Prune
mirror_prune=Rimuovi
mirror_prune_desc=Remove any remote-tracking references that no longer exist on the remote
mirror_interval=Intervallo Mirror (in ore)
mirror_address=Indirizzo del mirror
@@ -425,14 +425,14 @@ file_raw=Originale
file_history=Cronologia
file_view_raw=Vedi originale
file_permalink=Permalink
file_too_large=This file is too large to be shown
file_too_large=Questo file è troppo grande per essere mostrato
editor.new_file=New file
editor.upload_file=Upload file
editor.edit_file=Edit file
editor.preview_changes=Preview Changes
editor.cannot_edit_non_text_files=Cannot edit non-text files
editor.edit_this_file=Edit this file
editor.new_file=Nuovo file
editor.upload_file=Carica File
editor.edit_file=Modifica file
editor.preview_changes=Anteprima modifiche
editor.cannot_edit_non_text_files=Non è possibile modificare i file non di testo
editor.edit_this_file=Modifica questo file
editor.must_be_on_a_branch=You must be on a branch to make or propose changes to this file
editor.fork_before_edit=You must fork this repository before editing the file
editor.delete_this_file=Delete this file
@@ -457,7 +457,7 @@ editor.branch_already_exists=Branch '%s' already exists in this repository.
editor.directory_is_a_file=Entry '%s' in the parent path is a file not a directory in this repository.
editor.filename_is_a_directory=The filename '%s' is an existing directory in this repository.
editor.file_editing_no_longer_exists=The file '%s' you are editing no longer exists in the repository.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" rel="noopener" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
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
@@ -690,7 +690,7 @@ settings.search_user_placeholder=Cerca utente...
settings.org_not_allowed_to_be_collaborator=Un'organizzazione non può essere aggiunta come collaboratore.
settings.user_is_org_member=L'utente è un membro dell'organizzazione che non può essere aggiunto come collaboratore.
settings.add_webhook=Aggiungi Webhook
settings.hooks_desc=I Webhooks sono molto simili a un basilare evento trigger HTTP POST. Ogni volta che qualcosa si verifica in Gitea, tratteremo la notifica all'host di destinazione specificato. Ulteriori informazioni in questa <a target="_blank" href="%s">Guida ai Webhooks</a>.
settings.hooks_desc=I Webhooks sono molto simili a un basilare evento trigger HTTP POST. Ogni volta che qualcosa si verifica in Gitea, tratteremo la notifica all'host di destinazione specificato. Ulteriori informazioni in questa <a target="_blank" rel="noopener" href="%s">Guida ai Webhooks</a>.
settings.webhook_deletion=Elimina Webhook
settings.webhook_deletion_desc=Delete this webhook will remove its information and all delivery history. Do you want to continue?
settings.webhook_deletion_success=Il Webhook è stato eliminato con successo!
@@ -707,7 +707,7 @@ settings.githook_edit_desc=Se l'hook è inattivo, sarà presentato un contenuto
settings.githook_name=Nome hook
settings.githook_content=Contenuto hook
settings.update_githook=Aggiorna Hook
settings.add_webhook_desc=Gitea manderà una richiesta <code>POST</code> all'URL specificata, insieme alle informazioni sull'evento avvenuto. Puoi anche specificare quale tipo di formato dati vorresti ottenere all'innesco dell'hook (JSON, x-www-form-urlencoded, XML, ecc). Puoi trovare più informazioni nella nostra <a target="_blank" href="%s">Guida ai Webhook</a>.
settings.add_webhook_desc=Gitea manderà una richiesta <code>POST</code> all'URL specificata, insieme alle informazioni sull'evento avvenuto. Puoi anche specificare quale tipo di formato dati vorresti ottenere all'innesco dell'hook (JSON, x-www-form-urlencoded, XML, ecc). Puoi trovare più informazioni nella nostra <a target="_blank" rel="noopener" href="%s">Guida ai Webhook</a>.
settings.payload_url=Payload URL
settings.content_type=Content Type
settings.secret=Secret

View File

@@ -47,7 +47,7 @@ cancel=キャンセル
[install]
install=インストール
title=インストールをする前に必要な準備をしましょう
docker_helper=DockerでGogsを稼動する場合は、このページに変更を加える前に、 <a target="_blank" href="%s">ガイドライン</a>をよく読んでください!
docker_helper=DockerでGogsを稼動する場合は、このページに変更を加える前に、 <a target="_blank" rel="noopener" href="%s">ガイドライン</a>をよく読んでください!
requite_db_desc=Gitea は、MySQL、PostgreSQL、SQLite3 または TiDB が必要です。
db_title=データベース設定
db_type=データベースの種類
@@ -194,7 +194,7 @@ CommitSummary=Commit summary
CommitMessage=Commit message
CommitChoice=Commit choice
TreeName=File path
Content=Content
Content=コンテンツ
require_error=空にできません
alpha_dash_error=アルファベット、数字、ハイフン"-"、アンダースコア"_"のいずれかの必要があります
@@ -248,7 +248,7 @@ form.name_pattern_not_allowed=ユーザ名のパターン '%s' は許可され
[settings]
profile=プロフィール
password=パスワード
avatar=Avatar
avatar=アバター
ssh_keys=SSH キー
social=SNSアカウント
applications=アプリケーション
@@ -269,7 +269,7 @@ change_username_prompt=この変更はリンクをアカウントに関連付け
continue=続行
cancel=キャンセル
lookup_avatar_by_mail=Lookup Avatar by mail
lookup_avatar_by_mail=メールからアバターを取得
federated_avatar_lookup=Federated Avatar Lookup
enable_custom_avatar=カスタムのアバターを有効にする
choose_new_avatar=新しいアバターを選択
@@ -351,7 +351,7 @@ visibility=公開/非公開
visiblity_helper=このリポジトリは<span class="ui red text">プライベート</span>です。
visiblity_helper_forced=サイト管理者は、強制的にすべての新しいリポジトリを<span class="ui red text"> プライベート</span> にしています。
visiblity_fork_helper=(この値の変更はすべてのフォークに適用されます)
clone_helper=クローンに関してお困りであれば<a target="_blank"href="%s"> ヘルプ</a> を参照しましょう。
clone_helper=クローンに関してお困りであれば<a target="_blank" rel="noopener"href="%s"> ヘルプ</a> を参照しましょう。
fork_repo=リポジトリをフォーク
fork_from=フォーク元
fork_visiblity_helper=フォークされたリポジトリの可視状態は変更できません。
@@ -370,7 +370,7 @@ mirror_prune_desc=Remove any remote-tracking references that no longer exist on
mirror_interval=ミラー 間隔(時)
mirror_address=ミラー アドレス
mirror_address_desc=Please include necessary user credentials in the address.
mirror_last_synced=Last Synced
mirror_last_synced=最終同期
watchers=ウォッチャー
stargazers=Stargazers
forks=フォーク
@@ -429,35 +429,35 @@ file_too_large=このファイルは大きすぎるため、表示できませ
editor.new_file=New file
editor.upload_file=Upload file
editor.edit_file=Edit file
editor.edit_file=ファイルを編集
editor.preview_changes=Preview Changes
editor.cannot_edit_non_text_files=Cannot edit non-text files
editor.edit_this_file=Edit this file
editor.edit_this_file=このファイルを編集
editor.must_be_on_a_branch=You must be on a branch to make or propose changes to this file
editor.fork_before_edit=You must fork this repository before editing the file
editor.delete_this_file=Delete this file
editor.delete_this_file=このファイルを削除
editor.must_have_write_access=You must have write access to make or propose changes to this file
editor.file_delete_success=File '%s' has been deleted successfully!
editor.name_your_file=Name your file...
editor.filename_help=To add directory, just type it and press /. To remove a directory, go to the beginning of the field and press backspace.
editor.or=or
editor.cancel_lower=cancel
editor.commit_changes=Commit Changes
editor.cancel_lower=キャンセル
editor.commit_changes=変更をコミット
editor.add_tmpl=Add '%s/<filename>'
editor.add=Add '%s'
editor.update=Update '%s'
editor.delete=Delete '%s'
editor.add='%s' を追加
editor.update='%s' を更新
editor.delete='%s' を削除
editor.commit_message_desc=Add an optional extended description...
editor.commit_directly_to_this_branch=Commit directly to the <strong class="branch-name">%s</strong> branch.
editor.create_new_branch=Create a <strong>new branch</strong> for this commit and start a pull request.
editor.new_branch_name_desc=New branch name...
editor.cancel=Cancel
editor.cancel=キャンセル
editor.filename_cannot_be_empty=Filename cannot be empty.
editor.branch_already_exists=Branch '%s' already exists in this repository.
editor.directory_is_a_file=Entry '%s' in the parent path is a file not a directory in this repository.
editor.filename_is_a_directory=The filename '%s' is an existing directory in this repository.
editor.file_editing_no_longer_exists=The file '%s' you are editing no longer exists in the repository.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" rel="noopener" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
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
@@ -616,7 +616,7 @@ wiki.save_page=ページを保存
wiki.last_commit_info=%s このページを編集 %s
wiki.edit_page_button=編集
wiki.new_page_button=新規ページ
wiki.delete_page_button=Delete Page
wiki.delete_page_button=ページの削除
wiki.delete_page_notice_1=This will delete the page <code>"%s"</code>. Please be certain.
wiki.page_already_exists=既に同じ名前のWiki ページが存在します。
wiki.pages=ページ
@@ -625,15 +625,15 @@ wiki.last_updated=最終更新 %s
settings=設定
settings.options=オプション
settings.collaboration=コラボレーション
settings.collaboration.admin=Admin
settings.collaboration.write=Write
settings.collaboration.read=Read
settings.collaboration.admin=管理
settings.collaboration.write=書込
settings.collaboration.read=読込
settings.collaboration.undefined=Undefined
settings.hooks=Webhooks
settings.githooks=Git のフック
settings.basic_settings=基本設定
settings.mirror_settings=Mirror Settings
settings.sync_mirror=Sync Now
settings.sync_mirror=今すぐ同期
settings.mirror_sync_in_progress=Mirror syncing is in progress, please refresh page in about a minute.
settings.site=公式サイト
settings.update_settings=設定の更新
@@ -649,7 +649,7 @@ settings.use_internal_issue_tracker=Use builtin lightweight issue tracker
settings.use_external_issue_tracker=外部課題トラッキングシステムを使用
settings.tracker_url_format=外部課題トラッキングツール URLのフォーマット
settings.tracker_issue_style=External Issue Tracker Naming Style:
settings.tracker_issue_style.numeric=Numeric
settings.tracker_issue_style.numeric=数値
settings.tracker_issue_style.alphanumeric=Alphanumeric
settings.tracker_url_format_desc=You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
settings.pulls_desc=Enable pull requests to accept public contributions
@@ -665,10 +665,10 @@ settings.transfer_desc=リポジトリをあなたが管理者権限を持って
settings.transfer_notices_1=-新しい所有者が個人ユーザーの場合、あなたがアクセスできなくなります。
settings.transfer_notices_2=- You will conserve access if new owner is an organization and if you're one of the owners.
settings.transfer_form_title=操作を確認するために、以下の情報を入力してください。
settings.wiki_delete=Erase Wiki Data
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
settings.wiki_delete=Wikiのデータ消去
settings.wiki_delete_desc=Wikiのデータを消去すると元に戻すことは出来ません。よく確認してください。
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
settings.wiki_deletion_success=Wikiのデータ消去が完了しました。
settings.delete=このリポジトリを削除
settings.delete_desc=リポジトリを削除すると元に戻せません。確実に確認してください。
settings.delete_notices_1=-この操作は<strong>元に戻せません</strong> 。
@@ -690,7 +690,7 @@ settings.search_user_placeholder=Search users
settings.org_not_allowed_to_be_collaborator=組織を共同編集者として追加することはできません。
settings.user_is_org_member=ユーザーは組織の一員なので、共同編集者として追加することはできません。
settings.add_webhook=Webhook を追加
settings.hooks_desc=Webhooksは、Gogsで特定のイベントの発生時に指定された外部サービスに通知を許可します。イベントが発生すると、それぞれ指定されたUrlに、POSTリクエストが送られます。詳細はこちらのの <a target="_blank"href="%s"> Webhooks ガイド</a>をご覧ください。
settings.hooks_desc=Webhooksは、Gogsで特定のイベントの発生時に指定された外部サービスに通知を許可します。イベントが発生すると、それぞれ指定されたUrlに、POSTリクエストが送られます。詳細はこちらのの <a target="_blank" rel="noopener"href="%s"> Webhooks ガイド</a>をご覧ください。
settings.webhook_deletion=Webhook を削除
settings.webhook_deletion_desc=このwebhookを削除すると、すべての情報と配信履歴が削除されます。続行しますか
settings.webhook_deletion_success=Webhook が正常に削除されました。
@@ -707,7 +707,7 @@ settings.githook_edit_desc=もしフックがアクティブではない場合
settings.githook_name=フックの名前
settings.githook_content=コンテンツをフック
settings.update_githook=フックを更新
settings.add_webhook_desc=私たちは、指定されたURLに購読されたイベントの詳細を <code>POST</code>リクエストとして送信します。あなたは、異なるデータ受信モード(JSONまたは, <code>x-www-form-urlencoded</code>, <em>その他</em>) を設定することができます。詳細については、<a target="_blank" href="%s">Webhookガイド</a>を参照してください。
settings.add_webhook_desc=私たちは、指定されたURLに購読されたイベントの詳細を <code>POST</code>リクエストとして送信します。あなたは、異なるデータ受信モード(JSONまたは, <code>x-www-form-urlencoded</code>, <em>その他</em>) を設定することができます。詳細については、<a target="_blank" rel="noopener" href="%s">Webhookガイド</a>を参照してください。
settings.payload_url=ペイロードの URL
settings.content_type=コンテンツ タイプ
settings.secret=秘密

View File

@@ -6,7 +6,7 @@ explore=Izpētīt
help=Palīdzība
sign_in=Pierakstīties
sign_out=Izrakstīties
sign_up=Pieteikties
sign_up=Reģistrēties
register=Reģistrēties
website=Mājas lapa
version=Versija
@@ -47,7 +47,7 @@ cancel=Atcelt
[install]
install=Instalācija
title=Instalācijas soļi pirmo reizi palaižot
docker_helper=Ja Gitea tiek lietots zem Docker, izlasiet uzmanīgi <a target="_blank" href="%s">vadlīnijas</a>, pirms ko maināt šajā lapā!
docker_helper=Ja Gitea tiek lietots zem Docker, izlasiet uzmanīgi <a target="_blank" rel="noopener" href="%s">vadlīnijas</a>, pirms ko maināt šajā lapā!
requite_db_desc=Gitea nepieciešams MySQL, PostgreSQL, SQLite3 vai TiDB.
db_title=Datu bāzes iestatījumi
db_type=Datu bāzes veids
@@ -96,8 +96,8 @@ offline_mode=Iespējot bezsaistes režīmu
offline_mode_popup=Atspējot CDN arī produkcijas režīmā, visi resursu faili tiks piegādāti no servera.
disable_gravatar=Atspējot Gravatar pakalpojumu
disable_gravatar_popup=Atspējot Gravatar un citus avotus, visus avatarus augšupielādēts lietotāji vai izmantos noklusēto attēlu.
federated_avatar_lookup=Enable Federated Avatars Lookup
federated_avatar_lookup_popup=Enable federated avatars lookup to use federated open source service based on libravatar.
federated_avatar_lookup=Iespējot apvienoto profila bilžu meklētāju
federated_avatar_lookup_popup=Iespējot apvienoto profila bilžu meklētāju, lai izmantotu atvērtā koda apvienoto servisu balstītu uz libravatar.
disable_registration=Atspējot lietotāju reģistrāciju
disable_registration_popup=Atspējot lietotāju reģistrāciju, tikai administrators varēs izveidot jaunus lietotāju kontus.
enable_captcha=Iespējot drošības kodu
@@ -189,12 +189,12 @@ TeamName=Komandas nosaukums
AuthName=Autorizācijas nosaukums
AdminEmail=Admin e-pasta adrese
NewBranchName=New branch name
CommitSummary=Commit summary
CommitMessage=Commit message
CommitChoice=Commit choice
TreeName=File path
Content=Content
NewBranchName=Jauna atzara nosaukums
CommitSummary=Revīzijas kopsavilkums
CommitMessage=Revīzijas ziņojums
CommitChoice=Revīzijas izvēle
TreeName=Faila ceļš
Content=Saturs
require_error=` nedrīkst būt tukšs.`
alpha_dash_error=` drīkst saturēt tikai latīņu alfabēta burtus, ciparus vai domuzīmes (-_).`
@@ -269,8 +269,8 @@ change_username_prompt=Šī izmaiņa ietekmēs saites, kas norāda uz Jūsu kont
continue=Turpināt
cancel=Atcelt
lookup_avatar_by_mail=Lookup Avatar by mail
federated_avatar_lookup=Federated Avatar Lookup
lookup_avatar_by_mail=Meklēt profila bildes pēc e-pasta
federated_avatar_lookup=Apvienotais profila bilžu meklētājs
enable_custom_avatar=Iespējot maināmu profila attēlu
choose_new_avatar=Izvēlēties jaunu profila attēlu
update_avatar=Saglabāt profila bildi
@@ -351,13 +351,13 @@ visibility=Redzamība
visiblity_helper=Šis repozitorijs ir <span class="ui red text">privāts</span>
visiblity_helper_forced=Lapas administrators ir noteicis, ka visiem repozitorijiem ir jābūt <span class="ui red text">privātiem</span>
visiblity_fork_helper=(Šīs vērtības maiņa ietekmēs arī visus atdalītos repozitorijus)
clone_helper=Nepieciešama palīdzība kā veikt klonēšana? Apmeklējiet <a target="_blank" href="%s">Palīdzība</a> lapu!
clone_helper=Nepieciešama palīdzība kā veikt klonēšana? Apmeklējiet <a target="_blank" rel="noopener" href="%s">Palīdzība</a> lapu!
fork_repo=Atdalīt repozitoriju
fork_from=Atdalīt no
fork_visiblity_helper=Atdalītam repozitorijam nav iespējams nomainīt tā redzamību
repo_desc=Apraksts
repo_lang=Valoda
repo_gitignore_helper=Select .gitignore templates
repo_gitignore_helper=Izvēlieties .gitignore sagatavi
license=Licence
license_helper=Izvēlieties licences failu
readme=LasiMani
@@ -370,7 +370,7 @@ mirror_prune_desc=Izdzēst visas ārējās atsauces, kas ārējā repozitorijā
mirror_interval=Spoguļošanas intervāls (stundās)
mirror_address=Spoguļa adrese
mirror_address_desc=Lūdzu iekļaujiet adresē nepieciešamo lietotājvārdu/paroli.
mirror_last_synced=Last Synced
mirror_last_synced=Pēdējo reizi sinhronizēts
watchers=Novērotāji
stargazers=Zvaigžņdevēji
forks=Atdalītie repozitoriji
@@ -427,43 +427,43 @@ file_view_raw=Rādīt neapstrādātu
file_permalink=Patstāvīgā saite
file_too_large=Šis fails ir par lielu, lai to parādītu
editor.new_file=New file
editor.upload_file=Upload file
editor.edit_file=Edit file
editor.preview_changes=Preview Changes
editor.cannot_edit_non_text_files=Cannot edit non-text files
editor.edit_this_file=Edit this file
editor.must_be_on_a_branch=You must be on a branch to make or propose changes to this file
editor.fork_before_edit=You must fork this repository before editing the file
editor.delete_this_file=Delete this file
editor.must_have_write_access=You must have write access to make or propose changes to this file
editor.file_delete_success=File '%s' has been deleted successfully!
editor.name_your_file=Name your file...
editor.filename_help=To add directory, just type it and press /. To remove a directory, go to the beginning of the field and press backspace.
editor.or=or
editor.cancel_lower=cancel
editor.commit_changes=Commit Changes
editor.add_tmpl=Add '%s/<filename>'
editor.add=Add '%s'
editor.update=Update '%s'
editor.delete=Delete '%s'
editor.commit_message_desc=Add an optional extended description...
editor.commit_directly_to_this_branch=Commit directly to the <strong class="branch-name">%s</strong> branch.
editor.create_new_branch=Create a <strong>new branch</strong> for this commit and start a pull request.
editor.new_branch_name_desc=New branch name...
editor.cancel=Cancel
editor.filename_cannot_be_empty=Filename cannot be empty.
editor.branch_already_exists=Branch '%s' already exists in this repository.
editor.directory_is_a_file=Entry '%s' in the parent path is a file not a directory in this repository.
editor.filename_is_a_directory=The filename '%s' is an existing directory in this repository.
editor.file_editing_no_longer_exists=The file '%s' you are editing no longer exists in the repository.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
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.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'
editor.new_file=Jauns fails
editor.upload_file=Augšupielādēt failu
editor.edit_file=Labot failu
editor.preview_changes=Priekšskatīt izmaiņas
editor.cannot_edit_non_text_files=Nevar rediģēt failus, kas nav teksta faili
editor.edit_this_file=Rediģēt šo failu
editor.must_be_on_a_branch=Ir jābūt izvēlētam atzaram, lai varētu veikt vai piedāvāt izmaiņas šim failam
editor.fork_before_edit=Lai varētu labot failu ir nepieciešams atdalīt repozitoriju
editor.delete_this_file=Dzēst šo failu
editor.must_have_write_access=Jums ir jābūt rakstīšanas tiesībām, lai varētu veikt vai piedāvāt izmaiņas šim failam
editor.file_delete_success=Fails '%s' ir veiksmīgi izdzēsts!
editor.name_your_file=Ievadiet faila nosaukumu...
editor.filename_help=Lai pievienotu direktoriju, ierakstiet tās nosaukumu un nospiediet /. Lai noņemtu direktoriju, ielieciet kursoru pirms faila nosaukuma un nospiediet atpakaļatkāpes taustiņu.
editor.or=vai
editor.cancel_lower=atcelt
editor.commit_changes=Pabeigt revīziju
editor.add_tmpl=Pievienot '%s/<filename>'
editor.add=Pievienot '%s'
editor.update=Atjaunināt '%s'
editor.delete=Dzēst '%s'
editor.commit_message_desc=Pievienot neobligātu paplašinātu aprakstu...
editor.commit_directly_to_this_branch=Apstiprināt revīzijas izmaiņas atzarā <strong class="branch-name">%s</strong>.
editor.create_new_branch=Izveidot <strong>jaunu atzaru</strong> un izmaiņu pieprasījumu šai revīzijai.
editor.new_branch_name_desc=Jaunā atzara nosaukums...
editor.cancel=Atcelt
editor.filename_cannot_be_empty=Nav ievadīts faila nosaukums.
editor.branch_already_exists=Atzars '%s' šajā repozitorijā jau eksistē.
editor.directory_is_a_file=Ieraksts '%s' vecāka ceļā ir fails nevis direktorija šajā repozitorijā.
editor.filename_is_a_directory=Faila nosaukums '%s' sakrīt ar direktorijas nosaukumu šajā repozitorijā.
editor.file_editing_no_longer_exists=Fails '%s', ko labojat, vairs neeksistē repozitorijā.
editor.file_changed_while_editing=Faila saturs ir mainījies kopš brīža, kad sākāt to labot. <a target="_blank" rel="noopener" href="%s">Nospiediet šeit</a>, lai redzētu kas ir mainījies vai <strong>nospiediet atkārtoti pabeigt revīziju</strong>, lai pārrakstītu izmaiņas.
editor.file_already_exists=Fails ar nosaukumu '%s' repozitorijā jau eksistē.
editor.no_changes_to_show=Nav izmaiņu, ko rādīt.
editor.fail_to_update_file=Neizdevās izmainīt/izveidot failu '%s', kļūda: %v
editor.add_subdir=Pievienot apakšdirektoriju...
editor.unable_to_upload_files=Neizdevās augšupielādēt failus uz direktoriju '%s', kļūda: %v
editor.upload_files_to_dir=Augšupielādēt failus uz direktoriju '%s'
commits.commits=Revīzijas
commits.search=Meklēt revīzijas
@@ -490,11 +490,11 @@ issues.create=Pieteikt problēmu
issues.new_label=Jauna etiķete
issues.new_label_placeholder=Etiķetes nosaukums...
issues.create_label=Izveidot etiķeti
issues.label_templates.title=Load a predefined set of labels
issues.label_templates.info=There arent any labels yet. You can click on the "New Label" button above to create one or use a predefined set below.
issues.label_templates.helper=Select a label set
issues.label_templates.use=Use this label set
issues.label_templates.fail_to_load_file=Failed to load label template file '%s': %v
issues.label_templates.title=Ielādēt sākotnēji noteikto etiķešu kopu
issues.label_templates.info=Nav definēta neviena etiķete. Nospiediet pogu "Izveidot etiķeti", lai to izveidotu vai izmantojiet zemāk piedāvātās etiķetes.
issues.label_templates.helper=Izvēlieties etiķešu kopu
issues.label_templates.use=Izmantot šo etiķešu kopu
issues.label_templates.fail_to_load_file=Neizdevās ielādēt etiķetes sagataves failu '%s': %v
issues.open_tab=%d atvērti
issues.close_tab=%d aizvērti
issues.filter_label=Etiķete
@@ -536,7 +536,7 @@ issues.commit_ref_at=`pieminēja šo problēmu revīzijā <a id="%[1]s" href="#%
issues.poster=Autors
issues.collaborator=Līdzstrādnieks
issues.owner=Īpašnieks
issues.sign_in_require_desc=<a href="%s">Sign in</a> to join this conversation.
issues.sign_in_require_desc=<a href="%s">Pierakstieties</a>, lai pievienotos šai sarunai.
issues.edit=Labot
issues.cancel=Atcelt
issues.save=Saglabāt
@@ -551,8 +551,8 @@ issues.label_deletion=Etiķetes dzēšana
issues.label_deletion_desc=Dzēšot šo etiķeti, tā tiks noņemta no visām saistītajām problēmām. Vai vēlaties turpināt?
issues.label_deletion_success=Etiķete tika veiksmīgi izdzēsta!
issues.num_participants=%d dalībnieki
issues.attachment.open_tab=`Click to see "%s" in a new tab`
issues.attachment.download=`Click to download "%s"`
issues.attachment.open_tab=`Noklikšķiniet, lai apskatītos "%s" jaunā logā`
issues.attachment.download=`Noklikšķiniet, lai lejupielādētu "%s"`
pulls.new=Jauns izmaiņu pieprasījums
pulls.compare_changes=Salīdzināt izmaiņas
@@ -632,9 +632,9 @@ settings.collaboration.undefined=Nedefinētas
settings.hooks=Tīmekļa āķi
settings.githooks=Git āķi
settings.basic_settings=Pamatiestatījumi
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=Spoguļa iestatījumi
settings.sync_mirror=Sinhronizēt tagad
settings.mirror_sync_in_progress=Notiek spoguļa sinhronizācija, uzgaidiet aptuveni minūti un atjaunojiet lapu.
settings.site=Oficiālā mājas lapa
settings.update_settings=Mainīt iestatījumus
settings.change_reponame_prompt=Šī izmaiņa ietekmēs saites, kas ir saistītas ar šo repozitoriju.
@@ -644,8 +644,8 @@ settings.use_internal_wiki=Izmantot iebūvēto vikivietni
settings.use_external_wiki=Izmantot ārējo vikivietni
settings.external_wiki_url=Ārējās Vikivietnes adrese
settings.external_wiki_url_desc=Apmeklētāji tiks novirzīti uz adresi, kad viņi uzklikšķinās uz cilnes.
settings.issues_desc=Enable issue tracker
settings.use_internal_issue_tracker=Use builtin lightweight issue tracker
settings.issues_desc=Iespējot problēmu sekotāju
settings.use_internal_issue_tracker=Izmantot iebūvētu vieglu problēmu sekotāju
settings.use_external_issue_tracker=Izmantot ārējo problēmu sekotāju
settings.tracker_url_format=Ārējā problēmu sekotāja adreses formāts
settings.tracker_issue_style=Ārējā problēmu reģistra nosaukumu stils:
@@ -690,7 +690,7 @@ settings.search_user_placeholder=Meklēt lietotāju...
settings.org_not_allowed_to_be_collaborator=Organizāciju nav atļauts pievienot kā līdzstrādnieku.
settings.user_is_org_member=Lietotājs ir organizācijas biedrs, kas nevar tikt pievienots kā līdzstrādnieks.
settings.add_webhook=Pievienot tīmekļa āķi
settings.hooks_desc=Tīmekļa āķi ļauj paziņot ārējiem servisiem par noteiktiem notikomiem, kas notiek Git servisā. Kad iestāsies kāds notikums, katram ārējā servisa URL tiks nosūtīts POST pieprasījums. Lai uzzinātu sīkāk skatieties <a target="_blank" href="%s">Tīmekļa āķu rokasgrāmatā</a>.
settings.hooks_desc=Tīmekļa āķi ļauj paziņot ārējiem servisiem par noteiktiem notikomiem, kas notiek Git servisā. Kad iestāsies kāds notikums, katram ārējā servisa URL tiks nosūtīts POST pieprasījums. Lai uzzinātu sīkāk skatieties <a target="_blank" rel="noopener" href="%s">Tīmekļa āķu rokasgrāmatā</a>.
settings.webhook_deletion=Dzēst tīmekļa āķi
settings.webhook_deletion_desc=Dzēšot tīmekļa āķi tiks dzēsta visa ar to saistītā informācija un izpildes vēsture. Vai vēlaties turpināt?
settings.webhook_deletion_success=Tīmekļa āķis tika veiksmīgi izdzēsts!
@@ -707,7 +707,7 @@ settings.githook_edit_desc=Ja āķis nav aktīvs, tiks attēlots piemērs kā to
settings.githook_name=Āķa nosaukums
settings.githook_content=Āķa saturs
settings.update_githook=Labot āķi
settings.add_webhook_desc=Uz norādīto URL tiks nosūtīts <code>POST</code> pieprasījums ar notikuma datiem. Jūs varat norādīt arī datu formātu, kādā datus vēlaties saņemt (JSON, <code>x-www-form-urlencoded</code> <em>utt.</em>). Detalizētāku informāciju ir iespējams uzzināt <a target="_blank" href="%s">Tīmekļa āķu rokasgrāmatā</a>.
settings.add_webhook_desc=Uz norādīto URL tiks nosūtīts <code>POST</code> pieprasījums ar notikuma datiem. Jūs varat norādīt arī datu formātu, kādā datus vēlaties saņemt (JSON, <code>x-www-form-urlencoded</code> <em>utt.</em>). Detalizētāku informāciju ir iespējams uzzināt <a target="_blank" rel="noopener" href="%s">Tīmekļa āķu rokasgrāmatā</a>.
settings.payload_url=Vērtuma URL
settings.content_type=Satura tips
settings.secret=Noslēpums
@@ -720,8 +720,8 @@ settings.event_send_everything=Vēlos saņemt <strong>visu</strong>.
settings.event_choose=Atzīmēt, ko vēlos saņemt.
settings.event_create=Izveidot
settings.event_create_desc=Atzara vai taga izveidošana
settings.event_pull_request=Pull Request
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, or synchronized.
settings.event_pull_request=Izmaiņu pieprasījums
settings.event_pull_request_desc=Atvērts, aizvērts, atkāroti atvērts, labots, piešķirts vai noņemts izmaiņu pieprasījums, vai mainīta etiķete, vai veikta sinhronizācija.
settings.event_push=Izmaiņu nosūtīšana
settings.event_push_desc=Git izmaiņu nosūtīšana uz repozitoriju
settings.active=Aktīvs
@@ -1113,18 +1113,18 @@ config.cookie_life_time=Sīkdatņu glabāšanas ilgums
config.picture_config=Attēlu konfigurācija
config.picture_service=Lokāli attēli
config.disable_gravatar=Atspējot Gravatar
config.enable_federated_avatar=Enable Federated Avatars
config.enable_federated_avatar=Iespējot apvienotās profila bildes
config.git_config=Git konfigurācija
config.git_disable_diff_highlight=Disable Diff Syntax Highlight
config.git_max_diff_lines=Max Diff Lines (for a single file)
config.git_max_diff_line_characters=Max Diff Characters (for a single line)
config.git_max_diff_files=Max Diff Files (to be shown)
config.git_disable_diff_highlight=Atspējot salīdzināšanas sintakses iekrāsošanu
config.git_max_diff_lines=Maksimālais salīdzināmo rindu skaits vienam failam
config.git_max_diff_line_characters=Maksimālais salīdzināmo simbolu skaits vienai rindai
config.git_max_diff_files=Maksimālais salīdzināmo failu skaits, ko attēlot
config.git_gc_args=GC argumenti
config.git_migrate_timeout=Migrācijas noilgums
config.git_mirror_timeout=Mirror Update Timeout
config.git_clone_timeout=Clone Operation Timeout
config.git_pull_timeout=Pull Operation Timeout
config.git_mirror_timeout=Spoguļa atjaunošanas noilgums
config.git_clone_timeout=Klonēšanas darbības noilgums
config.git_pull_timeout=Izmaiņu saņemšanas darbības noilgums
config.git_gc_timeout=GC darbības noilgums
config.log_config=Žurnalizēšanas konfigurācija

View File

@@ -47,7 +47,7 @@ cancel=Annuleren
[install]
install=Installatie
title=Installatiestappen voor de eerste keer opstarten
docker_helper=Als u gebruik maakt Gitea binnen Docker, lees dan de <a target="_blank" href="%s">richtlijnen</a> voordat u iets veranderen op deze pagina!
docker_helper=Als u gebruik maakt Gitea binnen Docker, lees dan de <a target="_blank" rel="noopener" href="%s">richtlijnen</a> voordat u iets veranderen op deze pagina!
requite_db_desc=Gitea vereist MySQL, PostgreSQL, SQite3 of TiDB.
db_title=Database-instellingen
db_type=Database-type
@@ -193,8 +193,8 @@ NewBranchName=New branch name
CommitSummary=Commit summary
CommitMessage=Commit message
CommitChoice=Commit choice
TreeName=File path
Content=Content
TreeName=Bestandspad
Content=Inhoud
require_error=kan niet leeg zijn.
alpha_dash_error=moet een valide alfanumeriek of dash(-_) karakter zijn.
@@ -232,7 +232,7 @@ org_still_own_repo=De organisatie heeft nog eigendomen op repositories. U moet d
target_branch_not_exist=Doel branch bestaat niet
[user]
change_avatar=Change your avatar
change_avatar=Wijzig je profielfoto
join_on=Aangemeld op
repositories=repositories
activity=Openbare activiteit
@@ -248,7 +248,7 @@ form.name_pattern_not_allowed=Het gebruikersnaam patroon '%s' is niet toegestaan
[settings]
profile=Profiel
password=Wachtwoord
avatar=Avatar
avatar=Profielfoto
ssh_keys=SSH-sleutels
social=Sociale netwerk-accounts
applications=Toepassingen
@@ -269,7 +269,7 @@ change_username_prompt=Deze verandering zal de weg links hebben betrekking op uw
continue=Doorgaan
cancel=Annuleren
lookup_avatar_by_mail=Lookup Avatar by mail
lookup_avatar_by_mail=Zoek profielfoto per email
federated_avatar_lookup=Federated Avatar Lookup
enable_custom_avatar=Aangepaste avatar inschakelen
choose_new_avatar=Kies een nieuwe avatar
@@ -351,7 +351,7 @@ visibility=Zichtbaarheid
visiblity_helper=Deze repositorie is <span class="ui red text">privaat</span>
visiblity_helper_forced=Sitebeheerder heeft alle nieuwe repositories gedwongen <span class="ui red text">privé</span> te zijn
visiblity_fork_helper=(Verandering van deze waarde zal van invloed zijn op alle forks)
clone_helper=De behoeftehulp van klonen? Bezoek <a target="_blank" href="%s"> helpen</a>!
clone_helper=De behoeftehulp van klonen? Bezoek <a target="_blank" rel="noopener" href="%s"> helpen</a>!
fork_repo=Repository forken
fork_from=Afsplitsing van
fork_visiblity_helper=U kunt de zichtbaarheid van een geforkte repository niet aanpassen.
@@ -370,7 +370,7 @@ mirror_prune_desc=Remove any remote-tracking references that no longer exist on
mirror_interval=Mirror interval(uur)
mirror_address=Kopie-adres
mirror_address_desc=Gelieve noodzakelijke gebruikersgegevens in de adresbalk.
mirror_last_synced=Last Synced
mirror_last_synced=Laatste synchronisatie
watchers=Volgers
stargazers=Stargazers
forks=Forks
@@ -427,15 +427,15 @@ file_view_raw=Weergave ruwe
file_permalink=Permalink
file_too_large=This file is too large to be shown
editor.new_file=New file
editor.upload_file=Upload file
editor.edit_file=Edit file
editor.preview_changes=Preview Changes
editor.cannot_edit_non_text_files=Cannot edit non-text files
editor.edit_this_file=Edit this file
editor.must_be_on_a_branch=You must be on a branch to make or propose changes to this file
editor.fork_before_edit=You must fork this repository before editing the file
editor.delete_this_file=Delete this file
editor.new_file=Nieuw bestand
editor.upload_file=Bestand uploaden
editor.edit_file=Bewerk bestand
editor.preview_changes=Wijzigingen nagaan
editor.cannot_edit_non_text_files=Kan niet-tekstbestanden niet bewerken
editor.edit_this_file=Bestand aanpassen
editor.must_be_on_a_branch=Je moet in een branch zijn om aanpassingen te maken of voor te stellen
editor.fork_before_edit=Je moet deze repository eerst vorken om dit bestand aan te kunnen passen
editor.delete_this_file=Verwijder dit bestand
editor.must_have_write_access=You must have write access to make or propose changes to this file
editor.file_delete_success=File '%s' has been deleted successfully!
editor.name_your_file=Name your file...
@@ -457,7 +457,7 @@ editor.branch_already_exists=Branch '%s' already exists in this repository.
editor.directory_is_a_file=Entry '%s' in the parent path is a file not a directory in this repository.
editor.filename_is_a_directory=The filename '%s' is an existing directory in this repository.
editor.file_editing_no_longer_exists=The file '%s' you are editing no longer exists in the repository.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" rel="noopener" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
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
@@ -690,7 +690,7 @@ settings.search_user_placeholder=Zoek gebruiker...
settings.org_not_allowed_to_be_collaborator=De organisatie kan niet toegevoegd worden als medewerker.
settings.user_is_org_member=Gebruiker is lid van de organisatie die als een medewerker kan niet worden toegevoegd.
settings.add_webhook=Webhook toevoegen
settings.hooks_desc=Webhooks dat de externe diensten om kennisgevingen te ontvangen wanneer bepaalde gebeurtenissen op Gitea plaatsvinden. Wanneer de opgegeven gebeurtenissen plaatsvinden, sturen we een POST-aanvraag naar elk van de URL's die u opgeeft. Meer informatie vindt u in onze <a target="_blank" href="%s"> Webhooks gids</a>.
settings.hooks_desc=Webhooks dat de externe diensten om kennisgevingen te ontvangen wanneer bepaalde gebeurtenissen op Gitea plaatsvinden. Wanneer de opgegeven gebeurtenissen plaatsvinden, sturen we een POST-aanvraag naar elk van de URL's die u opgeeft. Meer informatie vindt u in onze <a target="_blank" rel="noopener" href="%s"> Webhooks gids</a>.
settings.webhook_deletion=Webhook verwijderen
settings.webhook_deletion_desc=Verwijderen van deze webhook zal de informatie en alle geschiedenis verwijderen. Wilt u doorgaan?
settings.webhook_deletion_success=Webhook is succesvol verwijderd!
@@ -707,7 +707,7 @@ settings.githook_edit_desc=Als haak niet actief is, zal monster inhoud worden ge
settings.githook_name=Haak naam
settings.githook_content=Haak inhoud
settings.update_githook=Haak bijwerken
settings.add_webhook_desc=We sturen een <code>POST</code>-aanvraag naar de onderstaande URL met details voor alle geplaatste gebeurtenissen. U kunt ook opgeven welke gegevensindeling u wenst te ontvangen (JSON, <code>x-1-800-www-Dell-vorm-urlencoded</code>, <em>enz</em>.). Meer informatie kan gevonden worden in <a target="_blank" href="%s"> Webhooks gids</a>.
settings.add_webhook_desc=We sturen een <code>POST</code>-aanvraag naar de onderstaande URL met details voor alle geplaatste gebeurtenissen. U kunt ook opgeven welke gegevensindeling u wenst te ontvangen (JSON, <code>x-1-800-www-Dell-vorm-urlencoded</code>, <em>enz</em>.). Meer informatie kan gevonden worden in <a target="_blank" rel="noopener" href="%s"> Webhooks gids</a>.
settings.payload_url=Nettolading URL
settings.content_type=Content type
settings.secret=Geheim

View File

@@ -47,7 +47,7 @@ cancel=Anuluj
[install]
install=Instalacja
title=Kroki instalacyjne dla pierwszego uruchomienia
docker_helper=Jeśli używasz Gitea wewnątrz Dockera, proszę przeczytaj <a target="_blank" href="%s">wytyczne</a>, zanim zmienisz coś na tej stronie!
docker_helper=Jeśli używasz Gitea wewnątrz Dockera, proszę przeczytaj <a target="_blank" rel="noopener" href="%s">wytyczne</a>, zanim zmienisz coś na tej stronie!
requite_db_desc=Gitea wymaga MySQL, PostgreSQL, SQLite3 lub TiDB.
db_title=Ustawienia bazy danych
db_type=Typ bazy danych
@@ -189,11 +189,11 @@ TeamName=Nazwa zespołu
AuthName=Nazwa autoryzacji
AdminEmail=E-mail administratora
NewBranchName=New branch name
NewBranchName=Nazwa nowej gałęzi
CommitSummary=Commit summary
CommitMessage=Commit message
CommitChoice=Commit choice
TreeName=File path
TreeName=Ścieżka pliku
Content=Content
require_error=` nie może być puste.`
@@ -351,7 +351,7 @@ visibility=Widoczność
visiblity_helper=To repozytorium jest <span class="ui red text">prywatne</span>
visiblity_helper_forced=Administrator systemu wymaga, żeby wszystkie nowe repozytoria były <span class="ui red text">Prywatne</span>
visiblity_fork_helper=(Zmiana tej wartości wpłynie na wszystkie forki)
clone_helper=Potrzebujesz pomocy z klonowaniem? Odwiedź <a target="_blank" href="%s">Pomoc</a>!
clone_helper=Potrzebujesz pomocy z klonowaniem? Odwiedź <a target="_blank" rel="noopener" href="%s">Pomoc</a>!
fork_repo=Sforkowane
fork_from=Forkuj z
fork_visiblity_helper=Fork nie może zmieniać swojej widoczności
@@ -434,7 +434,7 @@ editor.preview_changes=Preview Changes
editor.cannot_edit_non_text_files=Cannot edit non-text files
editor.edit_this_file=Edit this file
editor.must_be_on_a_branch=You must be on a branch to make or propose changes to this file
editor.fork_before_edit=You must fork this repository before editing the file
editor.fork_before_edit=Musisz sforkować to repozytorium przed edycją tego pliku
editor.delete_this_file=Delete this file
editor.must_have_write_access=You must have write access to make or propose changes to this file
editor.file_delete_success=File '%s' has been deleted successfully!
@@ -457,7 +457,7 @@ editor.branch_already_exists=Branch '%s' already exists in this repository.
editor.directory_is_a_file=Entry '%s' in the parent path is a file not a directory in this repository.
editor.filename_is_a_directory=The filename '%s' is an existing directory in this repository.
editor.file_editing_no_longer_exists=The file '%s' you are editing no longer exists in the repository.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" rel="noopener" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
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
@@ -493,7 +493,7 @@ issues.create_label=Utwórz etykietę
issues.label_templates.title=Load a predefined set of labels
issues.label_templates.info=There arent any labels yet. You can click on the "New Label" button above to create one or use a predefined set below.
issues.label_templates.helper=Select a label set
issues.label_templates.use=Use this label set
issues.label_templates.use=Użyj ten zestaw etykiet
issues.label_templates.fail_to_load_file=Failed to load label template file '%s': %v
issues.open_tab=Otwarte %d
issues.close_tab=Zamknięte %d
@@ -536,7 +536,7 @@ issues.commit_ref_at=`wspomina ten problem w commicie <a id="%[1]s" href="#%[1]s
issues.poster=Autor
issues.collaborator=Współpracownik
issues.owner=Właściciel
issues.sign_in_require_desc=<a href="%s">Sign in</a> to join this conversation.
issues.sign_in_require_desc=<a href="%s"> Zaloguj się</a>, aby dołączyć do tej rozmowy.
issues.edit=Edytuj
issues.cancel=Anuluj
issues.save=Zapisz
@@ -551,8 +551,8 @@ issues.label_deletion=Usunięcie etykiety
issues.label_deletion_desc=Usunięcie tej etykiety spowoduje usuniecie jej ze wszystkich powiązanych problemów. Czy na pewno chcesz kontynuować?
issues.label_deletion_success=Etykieta została usunięta pomyślnie!
issues.num_participants=%d uczestników
issues.attachment.open_tab=`Click to see "%s" in a new tab`
issues.attachment.download=`Click to download "%s"`
issues.attachment.open_tab=`Kliknij, aby zobaczyć "%s" w nowej karcie`
issues.attachment.download=`Kliknij, aby pobrać "%s"`
pulls.new=Nowy pull request
pulls.compare_changes=Porównaj zmiany
@@ -633,14 +633,14 @@ settings.hooks=Webhooki
settings.githooks=Hooki Git
settings.basic_settings=Ustawienia podstawowe
settings.mirror_settings=Mirror Settings
settings.sync_mirror=Sync Now
settings.sync_mirror=Synchronizuj teraz
settings.mirror_sync_in_progress=Mirror syncing is in progress, please refresh page in about a minute.
settings.site=Oficjalna Strona
settings.update_settings=Aktualizuj ustawienia
settings.change_reponame_prompt=Zmiana nazwy repozytorium wpłynie na linki do niego.
settings.advanced_settings=Ustawienia zaawansowane
settings.wiki_desc=Enable wiki system
settings.use_internal_wiki=Use builtin wiki
settings.wiki_desc=Włącz system wiki
settings.use_internal_wiki=Użyj wbudowanego wiki
settings.use_external_wiki=Użyj zewnętrznego Wiki
settings.external_wiki_url=Adres URL zewnętrznego Wiki
settings.external_wiki_url_desc=Odwiedzający zostaną przekierowani do adresu URL po kliknięciu zakładki.
@@ -690,7 +690,7 @@ settings.search_user_placeholder=Szukaj użytkownika...
settings.org_not_allowed_to_be_collaborator=Organizacji nie można dodać jako współpracownika.
settings.user_is_org_member=Użytkownik jest członkiem organizacji, który nie może być dodany jako współpracownik.
settings.add_webhook=Dodaj webhooka
settings.hooks_desc=Webooki działają tak jak proste wywołania HTTP POST. Jeśli cokolwiek zdarzy się w Gitea, wyślemy powiadomienie do wybranego hosta. Więcej informacji można znaleźć w <a target="_blank" href="%s">przewodniku webhooków</a>.
settings.hooks_desc=Webooki działają tak jak proste wywołania HTTP POST. Jeśli cokolwiek zdarzy się w Gitea, wyślemy powiadomienie do wybranego hosta. Więcej informacji można znaleźć w <a target="_blank" rel="noopener" href="%s">przewodniku webhooków</a>.
settings.webhook_deletion=Usuń webhooka
settings.webhook_deletion_desc=Usunięcie tego webooka spowoduje usunięcie powiązanych informacji i wpisów w historii. Czy chcesz kontynuować?
settings.webhook_deletion_success=Webhook został pomyślnie usunięty!
@@ -707,7 +707,7 @@ settings.githook_edit_desc=Jeśli hook jest nieaktywny, zaprezentowana zostanie
settings.githook_name=Nazwa hooka
settings.githook_content=Treść hooka
settings.update_githook=Zaktualizuj hook
settings.add_webhook_desc=Wyślemy żądanie <code>POST</code> pod poniższy adres ze szczegółami zdarzeń. Możesz również ustalić format danych zapytania (JSON, x-www-form-urlencoded, XML, itp.). Więcej informacji można znaleźć w <a target="_blank" href="%s">przewodniku webhooków</a>.
settings.add_webhook_desc=Wyślemy żądanie <code>POST</code> pod poniższy adres ze szczegółami zdarzeń. Możesz również ustalić format danych zapytania (JSON, x-www-form-urlencoded, XML, itp.). Więcej informacji można znaleźć w <a target="_blank" rel="noopener" href="%s">przewodniku webhooków</a>.
settings.payload_url=URL do wywołania
settings.content_type=Typ zawartości
settings.secret=Sekret
@@ -1115,13 +1115,13 @@ config.picture_service=Serwis obrazów
config.disable_gravatar=Wyłącz Gravatara
config.enable_federated_avatar=Enable Federated Avatars
config.git_config=Git Configuration
config.git_config=Konfiguracja Git
config.git_disable_diff_highlight=Disable Diff Syntax Highlight
config.git_max_diff_lines=Max Diff Lines (for a single file)
config.git_max_diff_line_characters=Max Diff Characters (for a single line)
config.git_max_diff_files=Max Diff Files (to be shown)
config.git_gc_args=GC Arguments
config.git_migrate_timeout=Migration Timeout
config.git_migrate_timeout=Limit czasu migracji
config.git_mirror_timeout=Mirror Update Timeout
config.git_clone_timeout=Clone Operation Timeout
config.git_pull_timeout=Pull Operation Timeout

File diff suppressed because it is too large Load Diff

View File

@@ -47,7 +47,7 @@ cancel=Отмена
[install]
install=Установка
title=Установочные шаги для первого запуска
docker_helper=Если вы запускаете Gitea внутри Docker, пожалуйста прочтите <a target="_blank" href="%s">эти советы</a> внимательно перед тем как что-либо изменить на этой странице!
docker_helper=Если вы запускаете Gitea внутри Docker, пожалуйста прочтите <a target="_blank" rel="noopener" href="%s">эти советы</a> внимательно перед тем как что-либо изменить на этой странице!
requite_db_desc=Gitea требует MySQL, PostgreSQL, SQLite3 или TiDB.
db_title=Настройки базы данных
db_type=Тип базы данных
@@ -96,7 +96,7 @@ offline_mode=Включение офлайн режима
offline_mode_popup=Отключить CDN даже в производственном режиме, все файлы ресурсов будут раздаваться локально.
disable_gravatar=Отключить службу Gravatar
disable_gravatar_popup=Отключить Gravatar и пользовательские источники, все аватары по-умолчанию загружаются пользователями.
federated_avatar_lookup=Enable Federated Avatars Lookup
federated_avatar_lookup=Включить поиск внешних Аватаров
federated_avatar_lookup_popup=Enable federated avatars lookup to use federated open source service based on libravatar.
disable_registration=Отключить самостоятельную регистрацию
disable_registration_popup=Запретить пользователям самостоятельную регистрацию, только администратор может создавать аккаунты.
@@ -269,8 +269,8 @@ change_username_prompt=Это изменение может повлечь за
continue=Далее
cancel=Отмена
lookup_avatar_by_mail=Lookup Avatar by mail
federated_avatar_lookup=Federated Avatar Lookup
lookup_avatar_by_mail=Найти Аватар по адресу эл. почты
federated_avatar_lookup=Найти внешний Аватар
enable_custom_avatar=Включить собственный аватар
choose_new_avatar=Выбрать новый аватар
update_avatar=Обновить настройку аватара
@@ -351,7 +351,7 @@ visibility=Видимость
visiblity_helper=<span class="ui red text">Личный</span> репозиторий
visiblity_helper_forced=Все новые репозитории являются <span class="ui red text">Личными</span> по желанию администратора сайта
visiblity_fork_helper=(Изменение этого значения затронет все ответвления)
clone_helper=Нужна помощь в клонировании? Посетите страницу <a target="_blank" href="%s">помощи</a>!
clone_helper=Нужна помощь в клонировании? Посетите страницу <a target="_blank" rel="noopener" href="%s">помощи</a>!
fork_repo=Ответвить репозиторий
fork_from=Ответвление от
fork_visiblity_helper=Ответвленному репозиторию нельзя поменять уровень видимости
@@ -431,14 +431,14 @@ editor.new_file=Новый файл
editor.upload_file=Загрузить файл
editor.edit_file=Редактировать файл
editor.preview_changes=Просмотр изменений
editor.cannot_edit_non_text_files=Cannot edit non-text files
editor.cannot_edit_non_text_files=Возможно редактировать только текстовые файлы
editor.edit_this_file=Отредактируйте этот файл
editor.must_be_on_a_branch=You must be on a branch to make or propose changes to this file
editor.fork_before_edit=Создайте ветку репозитория перед редактированием файла
editor.delete_this_file=Удалить файл
editor.must_have_write_access=You must have write access to make or propose changes to this file
editor.must_have_write_access=Вам необходимо иметь доступ на запись, чтобы вносить или предлагать правки этого файла
editor.file_delete_success=File '%s' has been deleted successfully!
editor.name_your_file=Name your file...
editor.name_your_file=Назовите свой файл...
editor.filename_help=To add directory, just type it and press /. To remove a directory, go to the beginning of the field and press backspace.
editor.or=или
editor.cancel_lower=отмена
@@ -453,16 +453,16 @@ editor.create_new_branch=Create a <strong>new branch</strong> for this commit an
editor.new_branch_name_desc=Новое название ветки...
editor.cancel=Отмена
editor.filename_cannot_be_empty=Имя файла не может быть пустым.
editor.branch_already_exists=Branch '%s' already exists in this repository.
editor.branch_already_exists=Ветка «%s» уже существует в этом репозитории.
editor.directory_is_a_file=Entry '%s' in the parent path is a file not a directory in this repository.
editor.filename_is_a_directory=The filename '%s' is an existing directory in this repository.
editor.file_editing_no_longer_exists=The file '%s' you are editing no longer exists in the repository.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
editor.file_already_exists=A file with name '%s' already exists in this repository.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" rel="noopener" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
editor.file_already_exists=Файл с именем «%s» уже существует в этом репозитории.
editor.no_changes_to_show=Нет изменений.
editor.fail_to_update_file=Failed to update/create file '%s' with error: %v
editor.fail_to_update_file=Не удалось обновить/создать файл «%s» из-за ошибки: %v
editor.add_subdir=Добавьте подкаталог...
editor.unable_to_upload_files=Failed to upload files to '%s' with error: %v
editor.unable_to_upload_files=Не удалось загрузить файлы в «%s» из-за ошибки: %v
editor.upload_files_to_dir=Загрузить файлы '%s'
commits.commits=Коммиты
@@ -490,7 +490,7 @@ issues.create=Добавить задачу
issues.new_label=Новая метка
issues.new_label_placeholder=Имя метки...
issues.create_label=Добавить метку
issues.label_templates.title=Load a predefined set of labels
issues.label_templates.title=Загрузить набор предопределённых меток
issues.label_templates.info=There arent any labels yet. You can click on the "New Label" button above to create one or use a predefined set below.
issues.label_templates.helper=Выберите метку
issues.label_templates.use=Использовать ярлык
@@ -536,7 +536,7 @@ issues.commit_ref_at=`упомянул эту задачу в коммите <a
issues.poster=Автор
issues.collaborator=Соавтор
issues.owner=Владелец
issues.sign_in_require_desc=<a href="%s">Sign in</a> to join this conversation.
issues.sign_in_require_desc=<a href="%s">Войдите</a>, чтобы присоединиться к обсуждению.
issues.edit=Изменить
issues.cancel=Отмена
issues.save=Сохранить
@@ -551,8 +551,8 @@ issues.label_deletion=Удаление метки
issues.label_deletion_desc=Удаление ярлыка затронет все связанные задачи. Продолжить?
issues.label_deletion_success=Метка была удалена успешно!
issues.num_participants=%d участников
issues.attachment.open_tab=`Click to see "%s" in a new tab`
issues.attachment.download=`Click to download "%s"`
issues.attachment.open_tab=`Нажмите, чтобы увидеть "%s" в новой вкладке`
issues.attachment.download=`Нажмите, чтобы скачать "%s"`
pulls.new=Новый запрос на слияние
pulls.compare_changes=Сравнить изменения
@@ -634,7 +634,7 @@ settings.githooks=Git хуки
settings.basic_settings=Основные параметры
settings.mirror_settings=Настройки Зеркала
settings.sync_mirror=Синхронизировать
settings.mirror_sync_in_progress=Mirror syncing is in progress, please refresh page in about a minute.
settings.mirror_sync_in_progress=Выполняется синхронизация Зеркала, пожалуйста, обновите эту страницу через минуту.
settings.site=Официальный сайт
settings.update_settings=Обновить настройки
settings.change_reponame_prompt=Это изменение повлияет на отношения ссылок к этому репозиторию.
@@ -675,7 +675,7 @@ settings.delete_notices_1=- Эта операция <strong>НЕ МОЖЕТ</str
settings.delete_notices_2=- Эта операция навсегда удалит всё из этого репозитория, включая данные Git, связанные с ним задачи, комментарии и права доступа для сотрудников.
settings.delete_notices_fork_1=- Все отвлетвления станут независимыми после удаления.
settings.deletion_success=Репозиторий был успешно удалён!
settings.update_settings_success=Настройка репозитория обновлена успешно.
settings.update_settings_success=Настройки репозитория обновлены успешно.
settings.transfer_owner=Новый владелец
settings.make_transfer=Выполнить передачу
settings.transfer_succeed=Владение репозиторием было успешно передано.
@@ -690,7 +690,7 @@ settings.search_user_placeholder=Поиск пользователя...
settings.org_not_allowed_to_be_collaborator=Организации не могут быть добавлены как соавторы.
settings.user_is_org_member=Пользователь является членом организации, члены которой не могут быть добавлены в качестве соавтора.
settings.add_webhook=Добавить Webhook
settings.hooks_desc=Webhooks позволяют внешним службам получать уведомления при возникновении определенных событий на Gitea. При возникновении указанных событий мы отправим запрос POST на каждый заданный вами URL. Узнать больше можно в нашем <a target="_blank" href="%s">Руководстве по Webhooks</a>.
settings.hooks_desc=Webhooks позволяют внешним службам получать уведомления при возникновении определенных событий на Gitea. При возникновении указанных событий мы отправим запрос POST на каждый заданный вами URL. Узнать больше можно в нашем <a target="_blank" rel="noopener" href="%s">Руководстве по Webhooks</a>.
settings.webhook_deletion=Удалить веб-хук
settings.webhook_deletion_desc=Удаление этого веб-хука приведет к удалению всей, связанной с ним, информации, включая историю. Хотите продолжить?
settings.webhook_deletion_success=Веб-хук успешно удален!
@@ -707,7 +707,7 @@ settings.githook_edit_desc=Если хук не активен, будет по
settings.githook_name=Название Hook'a
settings.githook_content=Перехватить содержание
settings.update_githook=Обновить Hook
settings.add_webhook_desc=Мы отправим запрос <code>POST</code> на указанный ниже URL с информацией о событиях. Можно также указать формат, в котором вы бы хотели получить данные (JSON, <code>x-www-form-urlencoded</code>, <em>и т.д.</em>). Дополнительную информацию можно найти в <a target="_blank" href="%s">Руководстве по Webhook</a>.
settings.add_webhook_desc=Мы отправим запрос <code>POST</code> на указанный ниже URL с информацией о событиях. Можно также указать формат, в котором вы бы хотели получить данные (JSON, <code>x-www-form-urlencoded</code>, <em>и т.д.</em>). Дополнительную информацию можно найти в <a target="_blank" rel="noopener" href="%s">Руководстве по Webhook</a>.
settings.payload_url=URL обработчика
settings.content_type=Тип содержимого
settings.secret=Secret
@@ -1113,13 +1113,13 @@ config.cookie_life_time=Время жизни файла cookie
config.picture_config=Настройка изображения
config.picture_service=Сервис изображений
config.disable_gravatar=Отключить Gravatar
config.enable_federated_avatar=Enable Federated Avatars
config.enable_federated_avatar=Включить внешние Аватары
config.git_config=Конфигурация GIT
config.git_disable_diff_highlight=Disable Diff Syntax Highlight
config.git_max_diff_lines=Max Diff Lines (for a single file)
config.git_max_diff_line_characters=Max Diff Characters (for a single line)
config.git_max_diff_files=Max Diff Files (to be shown)
config.git_disable_diff_highlight=Отключить подсветку синтаксиса Diff
config.git_max_diff_lines=Максимальное количество строк Diff (на файл)
config.git_max_diff_line_characters=Максимальное количество символов Diff (в строке)
config.git_max_diff_files=Максимальное количество Diff-файлов (при показе)
config.git_gc_args=Аргументы GC
config.git_migrate_timeout=Тайм-аут миграции
config.git_mirror_timeout=Время Ожидания Обновления Зеркала

View File

@@ -47,7 +47,7 @@ cancel=Откажи
[install]
install=Инсталација
title=Инсталационе кораке за првог покретања
docker_helper=Ако покрећете Gitea унутар Docker, молимо прочитајте <a target="_blank" href="%s">ове савете</a> пажљиво пре него што сте било шта променили на овој страници!
docker_helper=Ако покрећете Gitea унутар Docker, молимо прочитајте <a target="_blank" rel="noopener" href="%s">ове савете</a> пажљиво пре него што сте било шта променили на овој страници!
requite_db_desc=Gogs-у је потребно MySQL, PostgreSQL, SQLite3 или TiDB.
db_title=Подешавања базе
db_type=Тип базе података
@@ -351,7 +351,7 @@ visibility=Видљивост
visiblity_helper=<span class="ui red text">Приватно</span> спремиште
visiblity_helper_forced=Сва нова спремишта су <span class="ui red text">приватна</span> по одлуци администратора.
visiblity_fork_helper=(Промена ове вредности ће утицати на све гране)
clone_helper=Потребна вам помоћ клонирањем? Посетите страницу <a target="_blank" href="%s">Помоћ</a>!
clone_helper=Потребна вам помоћ клонирањем? Посетите страницу <a target="_blank" rel="noopener" href="%s">Помоћ</a>!
fork_repo=Креирај огранак спремишта
fork_from=Огранак од
fork_visiblity_helper=Ниво видљивости не може бити промењено за огранак спремишта.
@@ -457,7 +457,7 @@ editor.branch_already_exists=Грана '%s' већ постоји за ово
editor.directory_is_a_file='%s' је већ постојећа датотека а не директоријум у спремишту.
editor.filename_is_a_directory='%s' је постојећи директоријум у спремишту.
editor.file_editing_no_longer_exists=Датотека '%s' више не постоји у спремишту.
editor.file_changed_while_editing=Садржај датотеке је промењен од почетка уређивања. <a target="_blank" href="%s">Кликните овде</a> да видите шта је промењено или <strong>опет поднесите комит</strong> да пребришете промене.
editor.file_changed_while_editing=Садржај датотеке је промењен од почетка уређивања. <a target="_blank" rel="noopener" href="%s">Кликните овде</a> да видите шта је промењено или <strong>опет поднесите комит</strong> да пребришете промене.
editor.file_already_exists=Датотека са именом '%s' већ постоји у овом спремишту.
editor.no_changes_to_show=Нема никаквих промена.
editor.fail_to_update_file=Промена над '%s' није успело са грешком: %v
@@ -690,7 +690,7 @@ settings.search_user_placeholder=Претрага корисника...
settings.org_not_allowed_to_be_collaborator=Неможе се додати организација као сарадник.
settings.user_is_org_member=Корисник је члан организације и потом неможе бити додат као сарадник.
settings.add_webhook=Додај Webhook
settings.hooks_desc=Webhooks омогућавају спољашњим услугама да приме обавештења када се нешто одређено догоди на Gitea. Сазнајте више у овом <a target="_blank" href="%s">водичу за Webhooks</a>.
settings.hooks_desc=Webhooks омогућавају спољашњим услугама да приме обавештења када се нешто одређено догоди на Gitea. Сазнајте више у овом <a target="_blank" rel="noopener" href="%s">водичу за Webhooks</a>.
settings.webhook_deletion=Уклони Webhook
settings.webhook_deletion_desc=Брисање овог Webhook ће довести до уклањања сву наведену информацију, укључујући и историју. Да ли желите да наставите?
settings.webhook_deletion_success=Webhook успешно избрисан!
@@ -707,7 +707,7 @@ settings.githook_edit_desc=Aко Webhook није активан, примерн
settings.githook_name=Име Hook-а
settings.githook_content=Садржај Hook-а
settings.update_githook=Ажурирај Hook
settings.add_webhook_desc=Послаћемо захтев <code>POST</code> на наведену URL адресу са информацијама о догађајима. Такође можете да одредите формат у коме би желели да добију податке (JSON, x-www-form-urlencoded, XML, итд.). Додатне информације могу се наћи у <a target="_blank" href="%s">Упутство за Webhooks</a>.
settings.add_webhook_desc=Послаћемо захтев <code>POST</code> на наведену URL адресу са информацијама о догађајима. Такође можете да одредите формат у коме би желели да добију податке (JSON, x-www-form-urlencoded, XML, итд.). Додатне информације могу се наћи у <a target="_blank" rel="noopener" href="%s">Упутство за Webhooks</a>.
settings.payload_url=URL адреса за слање
settings.content_type=Тип садржаја
settings.secret=Тајна

1200
conf/locale/locale_sv-SE.ini Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -47,7 +47,7 @@ cancel=İptal
[install]
install=Kurulum
title=İlk Kez Çalıştırma İçin Kurulum Adımları
docker_helper=Gogs'u Docker içinde kullanıyorsanız bu sayfada herhangi bir değişiklik yapmadan önce lütfen <a target="_blank" href="%s">kılavuzu</a> dikkatlice okuyunuz!
docker_helper=Gogs'u Docker içinde kullanıyorsanız bu sayfada herhangi bir değişiklik yapmadan önce lütfen <a target="_blank" rel="noopener" href="%s">kılavuzu</a> dikkatlice okuyunuz!
requite_db_desc=Gitea MySQL, PostgreSQL, SQLite3 veya TiDB gerektirir.
db_title=Veritabanı Ayarları
db_type=Veritabanı Türü
@@ -193,7 +193,7 @@ NewBranchName=New branch name
CommitSummary=Commit summary
CommitMessage=Commit message
CommitChoice=Commit choice
TreeName=File path
TreeName=Dosya yolu
Content=Content
require_error=` boş olamaz.`
@@ -351,7 +351,7 @@ visibility=Görünürlük
visiblity_helper=Bu depo <span class="ui red text">Özel</span>
visiblity_helper_forced=Site yöneticisi tüm depolara erişimleri <span class="ui red text">Özel</span> olarak ayarlamaya zorladı
visiblity_fork_helper=(Bu değerin değişmesi tüm çatallamaları etkileyecektir)
clone_helper=Klonlama konusunda yardıma mı ihtiyacınız var? <a target="_blank" href="%s">Yardım</a> bağlantısını ziyaret edin!
clone_helper=Klonlama konusunda yardıma mı ihtiyacınız var? <a target="_blank" rel="noopener" href="%s">Yardım</a> bağlantısını ziyaret edin!
fork_repo=Depoyu Çatalla
fork_from=Buradan Çatalla
fork_visiblity_helper=Çatallanmış bir deponun görünürlüğünü değiştiremezsiniz.
@@ -429,9 +429,9 @@ file_too_large=Bu dosya sergilenmek için çok büyük
editor.new_file=New file
editor.upload_file=Upload file
editor.edit_file=Edit file
editor.edit_file=Dosya düzenle
editor.preview_changes=Preview Changes
editor.cannot_edit_non_text_files=Cannot edit non-text files
editor.cannot_edit_non_text_files=Metin dışı dosyalar düzenlenemez
editor.edit_this_file=Edit this file
editor.must_be_on_a_branch=You must be on a branch to make or propose changes to this file
editor.fork_before_edit=You must fork this repository before editing the file
@@ -441,7 +441,7 @@ editor.file_delete_success=File '%s' has been deleted successfully!
editor.name_your_file=Name your file...
editor.filename_help=To add directory, just type it and press /. To remove a directory, go to the beginning of the field and press backspace.
editor.or=or
editor.cancel_lower=cancel
editor.cancel_lower=iptal
editor.commit_changes=Commit Changes
editor.add_tmpl=Add '%s/<filename>'
editor.add=Add '%s'
@@ -451,13 +451,13 @@ editor.commit_message_desc=Add an optional extended description...
editor.commit_directly_to_this_branch=Commit directly to the <strong class="branch-name">%s</strong> branch.
editor.create_new_branch=Create a <strong>new branch</strong> for this commit and start a pull request.
editor.new_branch_name_desc=New branch name...
editor.cancel=Cancel
editor.cancel=İptal
editor.filename_cannot_be_empty=Filename cannot be empty.
editor.branch_already_exists=Branch '%s' already exists in this repository.
editor.directory_is_a_file=Entry '%s' in the parent path is a file not a directory in this repository.
editor.filename_is_a_directory=The filename '%s' is an existing directory in this repository.
editor.file_editing_no_longer_exists=The file '%s' you are editing no longer exists in the repository.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" rel="noopener" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
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
@@ -639,7 +639,7 @@ settings.site=Resmi Web Sitesi
settings.update_settings=Ayarları Güncelle
settings.change_reponame_prompt=Bu değişiklik, bağlantıların depoyla olan ilişkisini etkileyecektir.
settings.advanced_settings=Gelişmiş Ayarlar
settings.wiki_desc=Enable wiki system
settings.wiki_desc=Viki sıstemini etkinleştir
settings.use_internal_wiki=Use builtin wiki
settings.use_external_wiki=Harici Wiki kullan
settings.external_wiki_url=Harici Wiki bağlantısı
@@ -690,7 +690,7 @@ settings.search_user_placeholder=Kullanıcı ara...
settings.org_not_allowed_to_be_collaborator=Organizasyon, bir katkıcı olarak eklenemez.
settings.user_is_org_member=Kullanıcı organizasyon üyesi olduğu için katkıcı olarak eklenemez.
settings.add_webhook=Web İsteği Ekle
settings.hooks_desc=Web istekleri, HTTP POST olay tetikleyicileri gibidirler. Gitea'ta ne zaman bir şey olsa, hedef belirttiğiniz sunuculara bildirim yapabilecek duruma geliriz. Daha fazla bilgiyi <a target="_blank" href="%s">Web İstekleri Kılavuzu</a>'nda bulabilirsiniz.
settings.hooks_desc=Web istekleri, HTTP POST olay tetikleyicileri gibidirler. Gitea'ta ne zaman bir şey olsa, hedef belirttiğiniz sunuculara bildirim yapabilecek duruma geliriz. Daha fazla bilgiyi <a target="_blank" rel="noopener" href="%s">Web İstekleri Kılavuzu</a>'nda bulabilirsiniz.
settings.webhook_deletion=Web İsteğini Sil
settings.webhook_deletion_desc=Bu web isteğini silerseniz buna bağlı olan tüm bilgiler ve dağıtım geçmişi de silinecektir. Devam etmek istiyor musunuz?
settings.webhook_deletion_success=Web isteği başarıyla silindi!
@@ -707,7 +707,7 @@ settings.githook_edit_desc=İstek aktif değilse örnek içerik sunulacaktır.
settings.githook_name=İstek İsmi
settings.githook_content=İstek İçeriği
settings.update_githook=İsteği Güncelle
settings.add_webhook_desc=Gogs, meydana gelen olay ile birlikte belirttiğiniz bağlantıya bir <code>POST</code> isteği gönderecektir. Ayrıca tetiklenen istek (JSON, x-www-form-urlencoded, XML, vb) üzerine bir veri formatı belirtebilirsiniz. Daha fazla bilgiyi <a target="_blank" href="%s">Web İstekleri Kılavuzu</a> bağlantımızda bulabilirsiniz.
settings.add_webhook_desc=Gogs, meydana gelen olay ile birlikte belirttiğiniz bağlantıya bir <code>POST</code> isteği gönderecektir. Ayrıca tetiklenen istek (JSON, x-www-form-urlencoded, XML, vb) üzerine bir veri formatı belirtebilirsiniz. Daha fazla bilgiyi <a target="_blank" rel="noopener" href="%s">Web İstekleri Kılavuzu</a> bağlantımızda bulabilirsiniz.
settings.payload_url=Yük Bağlantısı
settings.content_type=İçerik Türü
settings.secret=Gizli

View File

@@ -47,7 +47,7 @@ cancel=取消
[install]
install=安装页面
title=首次运行安装程序
docker_helper=如果您正在使用 Docker 容器运行 Gitea请务必先仔细阅读 <a target="_blank" href="%s">官方文档</a> 后再对本页面进行填写。
docker_helper=如果您正在使用 Docker 容器运行 Gitea请务必先仔细阅读 <a target="_blank" rel="noopener" href="%s">官方文档</a> 后再对本页面进行填写。
requite_db_desc=Gitea 要求安装 MySQL、PostgreSQL、SQLite3 或 TiDB。
db_title=数据库设置
db_type=数据库类型
@@ -139,6 +139,9 @@ repos=仓库
users=用户
organizations=组织
search=搜索
repo_no_results = 没有匹配的仓库。
user_no_results = 没有匹配的用户。
org_no_results = 没有匹配的组织。
[auth]
create_new_account=创建帐户
@@ -352,7 +355,7 @@ visibility=可见性
visiblity_helper=该仓库为 <span class="ui red text">私有的</span>
visiblity_helper_forced=网站管理员已强制要求所有新建仓库必须为 <span class="ui red text">私有的</span>
visiblity_fork_helper=(修改该值将会影响到所有派生仓库)
clone_helper=不知道如何操作?访问 <a target="_blank" href="%s">此处</a> 查看帮助!
clone_helper=不知道如何操作?访问 <a target="_blank" rel="noopener" href="%s">此处</a> 查看帮助!
fork_repo=派生仓库
fork_from=派生自
fork_visiblity_helper=派生仓库无法修改可见性
@@ -458,7 +461,7 @@ editor.branch_already_exists=此仓库已存在名为 '%s' 的分支。
editor.directory_is_a_file=路径 '%s' 的父路径中包含此仓库已存在的文件名。
editor.filename_is_a_directory=文件名 '%s' 是此仓库中已存在的目录名。
editor.file_editing_no_longer_exists=您编辑的文件 '%s' 已经不存在于此仓库中。
editor.file_changed_while_editing=文件内容在您进行编辑时已经发生变动。<a target="_blank" href="%s">单击此处</a> 查看变动的具体内容,或者 <strong>再次提交</strong> 覆盖已发生的变动。
editor.file_changed_while_editing=文件内容在您进行编辑时已经发生变动。<a target="_blank" rel="noopener" href="%s">单击此处</a> 查看变动的具体内容,或者 <strong>再次提交</strong> 覆盖已发生的变动。
editor.file_already_exists=此仓库已经存在名为 '%s' 的文件。
editor.no_changes_to_show=没有可以显示的变更。
editor.fail_to_update_file=更新/创建文件 '%s' 时发生错误:%v
@@ -691,7 +694,7 @@ settings.search_user_placeholder=搜索用户...
settings.org_not_allowed_to_be_collaborator=组织不允许被添加为仓库协作者!
settings.user_is_org_member=被操作的用户是组织成员,因此无法添加为协作者!
settings.add_webhook=添加 Web 钩子
settings.hooks_desc=Web 钩子允许您设定在 Gitea 上发生指定事件时对指定 URL 发送 POST 通知。查看 <a target="_blank" href="%s">Webhooks 文档</a> 获取更多信息。
settings.hooks_desc=Web 钩子允许您设定在 Gitea 上发生指定事件时对指定 URL 发送 POST 通知。查看 <a target="_blank" rel="noopener" href="%s">Webhooks 文档</a> 获取更多信息。
settings.webhook_deletion=删除 Web 钩子
settings.webhook_deletion_desc=删除该 Web 钩子将会删除与其有关的信息和推送历史。是否继续?
settings.webhook_deletion_success=Web 钩子删除成功!
@@ -708,7 +711,7 @@ settings.githook_edit_desc=如果钩子未启动,则会显示样例文件中
settings.githook_name=钩子名称
settings.githook_content=钩子文本
settings.update_githook=更新钩子设置
settings.add_webhook_desc=我们会通过 <code>POST</code> 请求将订阅事件信息发送至向指定 URL 地址。您可以设置不同的数据接收方式JSON 或 <code>x-www-form-urlencoded</code>)。 请查阅 <a target="_blank" href="%s">Webhooks 文档</a> 获取更多信息。
settings.add_webhook_desc=我们会通过 <code>POST</code> 请求将订阅事件信息发送至向指定 URL 地址。您可以设置不同的数据接收方式JSON 或 <code>x-www-form-urlencoded</code>)。 请查阅 <a target="_blank" rel="noopener" href="%s">Webhooks 文档</a> 获取更多信息。
settings.payload_url=推送地址
settings.content_type=数据格式
settings.secret=密钥文本

View File

@@ -47,7 +47,7 @@ cancel=取消
[install]
install=安裝頁面
title=首次安裝步驟
docker_helper=如果您正在使用 Docker 容器運行 Gitea請務必先仔細閱讀 <a target="_blank" href="%s">官方文檔</a> 後再對本頁面進行填寫。
docker_helper=如果您正在使用 Docker 容器運行 Gitea請務必先仔細閱讀 <a target="_blank" rel="noopener" href="%s">官方文檔</a> 後再對本頁面進行填寫。
requite_db_desc=Gitea 要求安裝 MySQL、PostgreSQL、SQLite3 或 TiDB。
db_title=數據庫設置
db_type=資料庫類型
@@ -351,7 +351,7 @@ visibility=可見度
visiblity_helper=該倉庫為 <span class="ui red text">私有的</span>
visiblity_helper_forced=網站管理員已強制要求所有新建倉庫必須為 <span class="ui red text">私有的</span>
visiblity_fork_helper=(修改該值將會影響到所有派生倉庫)
clone_helper=不知道如何操作?訪問 <a target="_blank"href="%s"> 帮助説明</a>
clone_helper=不知道如何操作?訪問 <a target="_blank" rel="noopener"href="%s"> 帮助説明</a>
fork_repo=派生倉庫
fork_from=派生自
fork_visiblity_helper=派生倉庫無法修改可見性。
@@ -457,7 +457,7 @@ editor.branch_already_exists=Branch '%s' already exists in this repository.
editor.directory_is_a_file=Entry '%s' in the parent path is a file not a directory in this repository.
editor.filename_is_a_directory=The filename '%s' is an existing directory in this repository.
editor.file_editing_no_longer_exists=The file '%s' you are editing no longer exists in the repository.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" rel="noopener" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
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
@@ -690,7 +690,7 @@ settings.search_user_placeholder=搜索用戶...
settings.org_not_allowed_to_be_collaborator=Organization is not allowed to be added as a collaborator.
settings.user_is_org_member=被操作的用戶是組織成員,因此無法添加為協作者!
settings.add_webhook=添加 Web 鉤子
settings.hooks_desc=Web 鉤子允許您設定在 Gitea 上發生指定事件時對指定 URL 發送 POST 通知。查看 <a target="_blank" href="%s">Webhooks 文檔</a> 獲取更多信息。
settings.hooks_desc=Web 鉤子允許您設定在 Gitea 上發生指定事件時對指定 URL 發送 POST 通知。查看 <a target="_blank" rel="noopener" href="%s">Webhooks 文檔</a> 獲取更多信息。
settings.webhook_deletion=刪除 Web 鉤子
settings.webhook_deletion_desc=刪除該 Web 鉤子將會刪除與其有關的信息和推送歷史。是否繼續?
settings.webhook_deletion_success=Web 鉤子刪除成功!
@@ -707,7 +707,7 @@ settings.githook_edit_desc=如果鉤子未啟動,則會顯示樣例文件中
settings.githook_name=鉤子名稱
settings.githook_content=鉤子文本
settings.update_githook=更新鉤子設置
settings.add_webhook_desc=我們會通過 <code>POST</code> 請求將訂閱事件信息發送至向指定 URL 地址。您可以設置不同的數據接收方式JSON 或 <code>x-www-form-urlencoded</code>)。 請查閱 <a target="_blank" href="%s">Webhooks 指南</a>.
settings.add_webhook_desc=我們會通過 <code>POST</code> 請求將訂閱事件信息發送至向指定 URL 地址。您可以設置不同的數據接收方式JSON 或 <code>x-www-form-urlencoded</code>)。 請查閱 <a target="_blank" rel="noopener" href="%s">Webhooks 指南</a>.
settings.payload_url=推送地址
settings.content_type=數據格式
settings.secret=密鑰文本

View File

@@ -47,7 +47,7 @@ cancel=取消
[install]
install=安裝頁面
title=首次安裝步驟
docker_helper=如果您正在使用 Docker 容器運行 Gitea請務必先仔細閱讀 <a target="_blank" href="%s">官方文檔</a> 後再對本頁面進行填寫。
docker_helper=如果您正在使用 Docker 容器運行 Gitea請務必先仔細閱讀 <a target="_blank" rel="noopener" href="%s">官方文檔</a> 後再對本頁面進行填寫。
requite_db_desc=Gitea 要求安裝 MySQL、PostgreSQL、SQLite3 或 TiDB。
db_title=數據庫設置
db_type=資料庫類型
@@ -126,7 +126,7 @@ uname_holder=用戶名或郵箱
password_holder=密碼
switch_dashboard_context=切換控制面版用戶
my_repos=我的倉庫
show_more_repos=Show more repositories...
show_more_repos=顯示更多倉庫...
collaborative_repos=參與協作的倉庫
my_orgs=我的組織
my_mirrors=我的鏡像
@@ -151,7 +151,7 @@ forget_password=忘記密碼?
sign_up_now=還沒帳戶?馬上註冊。
confirmation_mail_sent_prompt=一封新的確認郵件已經被發送至 <b>%s</b>,請檢查您的收件箱並在 %d 小時內完成確認註冊操作。
active_your_account=激活您的帳戶
prohibit_login=Login Prohibited
prohibit_login=禁止登錄
prohibit_login_desc=Your account is prohibited to login, please contact site admin.
resent_limit_prompt=對不起,您請求發送激活郵件過於頻繁,請等待 3 分鐘後再試!
has_unconfirmed_mail=%s 您好,您有一封發送至( <b>%s</b>) 但未被確認的郵件。如果您未收到激活郵件,或需要重新發送,請單擊下方的按鈕。
@@ -189,12 +189,12 @@ TeamName=團隊名稱
AuthName=認證名稱
AdminEmail=管理員郵箱
NewBranchName=New branch name
NewBranchName=新的分支名稱
CommitSummary=Commit summary
CommitMessage=Commit message
CommitMessage=提交訊息
CommitChoice=Commit choice
TreeName=File path
Content=Content
TreeName=檔案路徑
Content=內容
require_error=不能為空。
alpha_dash_error=必須為英文字母、阿拉伯數字或橫線(-_
@@ -351,7 +351,7 @@ visibility=可見度
visiblity_helper=該倉庫為 <span class="ui red text">私有的</span>
visiblity_helper_forced=網站管理員已強制要求所有新建倉庫必須為 <span class="ui red text">私有的</span>
visiblity_fork_helper=(修改該值將會影響到所有派生倉庫)
clone_helper=不知道如何操作?訪問 <a target="_blank"href="%s"> 帮助説明</a>
clone_helper=不知道如何操作?訪問 <a target="_blank" rel="noopener"href="%s"> 帮助説明</a>
fork_repo=派生倉庫
fork_from=派生自
fork_visiblity_helper=派生倉庫無法修改可見性。
@@ -427,41 +427,41 @@ file_view_raw=查看原始文件
file_permalink=永久連結
file_too_large=This file is too large to be shown
editor.new_file=New file
editor.upload_file=Upload file
editor.edit_file=Edit file
editor.new_file=開新檔案
editor.upload_file=上傳檔案
editor.edit_file=編輯文件
editor.preview_changes=Preview Changes
editor.cannot_edit_non_text_files=Cannot edit non-text files
editor.edit_this_file=Edit this file
editor.cannot_edit_non_text_files=不能編輯非文字檔
editor.edit_this_file=編輯此文件
editor.must_be_on_a_branch=You must be on a branch to make or propose changes to this file
editor.fork_before_edit=You must fork this repository before editing the file
editor.delete_this_file=Delete this file
editor.delete_this_file=刪除此文件
editor.must_have_write_access=You must have write access to make or propose changes to this file
editor.file_delete_success=File '%s' has been deleted successfully!
editor.name_your_file=Name your file...
editor.filename_help=To add directory, just type it and press /. To remove a directory, go to the beginning of the field and press backspace.
editor.or=or
editor.cancel_lower=cancel
editor.or=
editor.cancel_lower=取消
editor.commit_changes=Commit Changes
editor.add_tmpl=Add '%s/<filename>'
editor.add=Add '%s'
editor.update=Update '%s'
editor.delete=Delete '%s'
editor.add=新增 '%s'
editor.update=更新 '%s'
editor.delete=刪除 '%s'
editor.commit_message_desc=Add an optional extended description...
editor.commit_directly_to_this_branch=Commit directly to the <strong class="branch-name">%s</strong> branch.
editor.create_new_branch=Create a <strong>new branch</strong> for this commit and start a pull request.
editor.new_branch_name_desc=New branch name...
editor.cancel=Cancel
editor.new_branch_name_desc=新的分支名稱...
editor.cancel=取消
editor.filename_cannot_be_empty=Filename cannot be empty.
editor.branch_already_exists=Branch '%s' already exists in this repository.
editor.directory_is_a_file=Entry '%s' in the parent path is a file not a directory in this repository.
editor.filename_is_a_directory=The filename '%s' is an existing directory in this repository.
editor.file_editing_no_longer_exists=The file '%s' you are editing no longer exists in the repository.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
editor.file_changed_while_editing=File content has been changed since you started editing. <a target="_blank" rel="noopener" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
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.no_changes_to_show=沒有可以顯示的變更。
editor.fail_to_update_file=Failed to update/create file '%s' with error: %v
editor.add_subdir=Add subdirectory...
editor.add_subdir=新增子目錄...
editor.unable_to_upload_files=Failed to upload files to '%s' with error: %v
editor.upload_files_to_dir=Upload files to '%s'
@@ -523,7 +523,7 @@ issues.open_title=開啟中
issues.closed_title=已關閉
issues.num_comments=%d 條評論
issues.commented_at=`commented <a href="#%s">%s</a>`
issues.delete_comment_confirm=Are you sure you want to delete this comment?
issues.delete_comment_confirm=您確定要刪除該條評論嗎?
issues.no_content=尚未有任何內容
issues.close_issue=關閉
issues.close_comment_issue=關閉及評論
@@ -551,8 +551,8 @@ issues.label_deletion=刪除標籤
issues.label_deletion_desc=刪除該標籤將會移除所有問題中相關的訊息。是否繼續?
issues.label_deletion_success=標籤刪除成功!
issues.num_participants=%d 參與者
issues.attachment.open_tab=`Click to see "%s" in a new tab`
issues.attachment.download=`Click to download "%s"`
issues.attachment.open_tab=`在新的標籤頁中查看 '%s'`
issues.attachment.download=`點擊下載 '%s'`
pulls.new=創建合併請求
pulls.compare_changes=對比文件變化
@@ -632,14 +632,14 @@ settings.collaboration.undefined=未定義
settings.hooks=管理 Web 鉤子
settings.githooks=管理 Git 鉤子
settings.basic_settings=基本設置
settings.mirror_settings=Mirror Settings
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.site=官方網站
settings.update_settings=更新倉庫設置
settings.change_reponame_prompt=該操作將會影響到所有與該倉庫有關的鏈接
settings.advanced_settings=高級設置
settings.wiki_desc=Enable wiki system
settings.wiki_desc=啓用 Wiki 系統
settings.use_internal_wiki=Use builtin wiki
settings.use_external_wiki=使用外部 wiki
settings.external_wiki_url=外部 Wiki 連結
@@ -690,7 +690,7 @@ settings.search_user_placeholder=搜索用戶...
settings.org_not_allowed_to_be_collaborator=組織不允許被加為協同者。
settings.user_is_org_member=被操作的用戶是組織成員,因此無法添加為協作者!
settings.add_webhook=添加 Web 鉤子
settings.hooks_desc=Web 鉤子允許您設定在 Gitea 上發生指定事件時對指定 URL 發送 POST 通知。查看 <a target="_blank" href="%s">Webhooks 文檔</a> 獲取更多信息。
settings.hooks_desc=Web 鉤子允許您設定在 Gitea 上發生指定事件時對指定 URL 發送 POST 通知。查看 <a target="_blank" rel="noopener" href="%s">Webhooks 文檔</a> 獲取更多信息。
settings.webhook_deletion=刪除 Web 鉤子
settings.webhook_deletion_desc=刪除該 Web 鉤子將會刪除與其有關的信息和推送歷史。是否繼續?
settings.webhook_deletion_success=Web 鉤子刪除成功!
@@ -707,7 +707,7 @@ settings.githook_edit_desc=如果鉤子未啟動,則會顯示樣例文件中
settings.githook_name=鉤子名稱
settings.githook_content=鉤子文本
settings.update_githook=更新鉤子設置
settings.add_webhook_desc=我們會通過 <code>POST</code> 請求將訂閱事件信息發送至向指定 URL 地址。您可以設置不同的數據接收方式JSON 或 <code>x-www-form-urlencoded</code>)。 請查閱 <a target="_blank" href="%s">Webhooks 指南</a>.
settings.add_webhook_desc=我們會通過 <code>POST</code> 請求將訂閱事件信息發送至向指定 URL 地址。您可以設置不同的數據接收方式JSON 或 <code>x-www-form-urlencoded</code>)。 請查閱 <a target="_blank" rel="noopener" href="%s">Webhooks 指南</a>.
settings.payload_url=推送地址
settings.content_type=數據格式
settings.secret=密鑰文本
@@ -720,7 +720,7 @@ settings.event_send_everything=推送 <strong>所有</strong> 事件
settings.event_choose=讓我選擇我的需要
settings.event_create=創建
settings.event_create_desc=創建分支或標籤
settings.event_pull_request=Pull Request
settings.event_pull_request=合併請求
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, or synchronized.
settings.event_push=推送
settings.event_push_desc=Git 倉庫推送

View File

@@ -1,111 +0,0 @@
# Docker for Gogs
Visit [Docker Hub](https://hub.docker.com/r/gogs/) see all available images and tags.
## Usage
To keep your data out of Docker container, we do a volume (`/var/gogs` -> `/data`) here, and you can change it based on your situation.
```
# Pull image from Docker Hub.
$ docker pull gogs/gogs
# Create local directory for volume.
$ mkdir -p /var/gogs
# Use `docker run` for the first time.
$ docker run --name=gogs -p 10022:22 -p 10080:3000 -v /var/gogs:/data gogs/gogs
# Use `docker start` if you have stopped it.
$ docker start gogs
```
Note: It is important to map the Gogs ssh service from the container to the host and set the appropriate SSH Port and URI settings when setting up Gogs for the first time. To access and clone Gogs Git repositories with the above configuration you would use: `git clone ssh://git@hostname:10022/username/myrepo.git` for example.
Files will be store in local path `/var/gogs` in my case.
Directory `/var/gogs` keeps Git repositories and Gogs data:
/var/gogs
|-- git
| |-- gogs-repositories
|-- ssh
| |-- # ssh public/private keys for Gogs
|-- gogs
|-- conf
|-- data
|-- log
### Volume with data container
If you're more comfortable with mounting data to a data container, the commands you execute at the first time will look like as follows:
```
# Create data container
docker run --name=gogs-data --entrypoint /bin/true gogs/gogs
# Use `docker run` for the first time.
docker run --name=gogs --volumes-from gogs-data -p 10022:22 -p 10080:3000 gogs/gogs
```
#### Using Docker 1.9 Volume command
```
# Create docker volume.
$ docker volume create --name gogs-data
# Use `docker run` for the first time.
$ docker run --name=gogs -p 10022:22 -p 10080:3000 -v gogs-data:/data gogs/gogs
```
## Settings
### Application
Most of settings are obvious and easy to understand, but there are some settings can be confusing by running Gogs inside Docker:
- **Repository Root Path**: keep it as default value `/home/git/gogs-repositories` because `start.sh` already made a symbolic link for you.
- **Run User**: keep it as default value `git` because `start.sh` already setup a user with name `git`.
- **Domain**: fill in with Docker container IP (e.g. `192.168.99.100`). But if you want to access your Gogs instance from a different physical machine, please fill in with the hostname or IP address of the Docker host machine.
- **SSH Port**: Use the exposed port from Docker container. For example, your SSH server listens on `22` inside Docker, but you expose it by `10022:22`, then use `10022` for this value. **Builtin SSH server is not recommended inside Docker Container**
- **HTTP Port**: Use port you want Gogs to listen on inside Docker container. For example, your Gogs listens on `3000` inside Docker, and you expose it by `10080:3000`, but you still use `3000` for this value.
- **Application URL**: Use combination of **Domain** and **exposed HTTP Port** values (e.g. `http://192.168.99.100:10080/`).
Full documentation of application settings can be found [here](https://gogs.io/docs/advanced/configuration_cheat_sheet.html).
### Container options
This container have some options available via environment variables, these options are opt-in features that can help the administration of this container:
- **SOCAT_LINK**:
- <u>Possible value:</u>
`true`, `false`, `1`, `0`
- <u>Default:</u>
`true`
- <u>Action:</u>
Bind linked docker container to localhost socket using socat.
Any exported port from a linked container will be binded to the matching port on localhost.
- <u>Disclaimer:</u>
As this option rely on the environment variable created by docker when a container is linked, this option should be deactivated in managed environment such as Rancher or Kubernetes (set to `0` or `false`)
- **RUN_CROND**:
- <u>Possible value:</u>
`true`, `false`, `1`, `0`
- <u>Default:</u>
`false`
- <u>Action:</u>
Request crond to be run inside the container. Its default configuration will periodically run all scripts from `/etc/periodic/${period}` but custom crontabs can be added to `/var/spool/cron/crontabs/`.
## Upgrade
:exclamation::exclamation::exclamation:<span style="color: red">**Make sure you have volumed data to somewhere outside Docker container**</span>:exclamation::exclamation::exclamation:
Steps to upgrade Gogs with Docker:
- `docker pull gogs/gogs`
- `docker stop gogs`
- `docker rm gogs`
- Finally, create container as the first time and don't forget to do same volume and port mapping.
## Known Issues
- The docker container can not currently be build on Raspberry 1 (armv6l) as our base image `alpine` does not have a `go` package available for this platform.

View File

@@ -1,36 +0,0 @@
#!/bin/sh
set -x
set -e
# Set temp environment vars
export GOPATH=/tmp/go
export PATH=${PATH}:${GOPATH}/bin
export GO15VENDOREXPERIMENT=1
# Install build deps
apk --no-cache --no-progress add --virtual build-deps build-base linux-pam-dev go
# Install glide
git clone -b 0.10.2 https://github.com/Masterminds/glide ${GOPATH}/src/github.com/Masterminds/glide
cd ${GOPATH}/src/github.com/Masterminds/glide
make build
go install
# Build Gogs
mkdir -p ${GOPATH}/src/github.com/gogits/
ln -s /app/gogs/ ${GOPATH}/src/github.com/go-gitea/gitea
cd ${GOPATH}/src/github.com/go-gitea/gitea
glide install
make build TAGS="sqlite cert pam"
# Cleanup GOPATH & vendoring dir
rm -r $GOPATH /app/gogs/vendor
# Remove build deps
apk --no-progress del build-deps
# Create git user for Gogs
adduser -H -D -g 'Gogs Git User' git -h /data/git -s /bin/bash && passwd -u git
echo "export GITEA_CUSTOM=${GITEA_CUSTOM}" >> /etc/profile

View File

@@ -13,4 +13,3 @@ ethers: db files
rpc: db files
netgroup: nis

2
docker/etc/profile.d/gitea.sh Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
export GITEA_CUSTOM=/data/gitea

View File

@@ -0,0 +1,2 @@
#!/bin/bash
exit 0

2
docker/etc/s6/gitea/finish Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
exit 0

6
docker/etc/s6/gitea/run Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/bash
[[ -f ./setup ]] && source ./setup
pushd /app/gitea > /dev/null
exec su-exec git /app/gitea/gitea web
popd

19
docker/etc/s6/gitea/setup Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/bash
if [ ! -d /data/git/.ssh ]; then
mkdir -p /data/git/.ssh
chmod 700 /data/git/.ssh
fi
if [ ! -f /data/git/.ssh/environment ]; then
echo "GITEA_CUSTOM=/data/gitea" >| /data/git/.ssh/environment
chmod 600 /data/git/.ssh/environment
fi
if [ ! -f /data/gitea/conf/app.ini ]; then
mkdir -p /data/gitea/conf
cp /etc/templates/app.ini /data/gitea/conf/app.ini
fi
chown -R git:git /data/gitea /app/gitea /data/git
chmod 0755 /data/gitea /app/gitea /data/git

2
docker/etc/s6/openssh/finish Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
exit 0

6
docker/etc/s6/openssh/run Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/bash
[[ -f ./setup ]] && source ./setup
pushd /root > /dev/null
exec su-exec root /usr/sbin/sshd -E /var/log/sshd.log -D
popd

29
docker/etc/s6/openssh/setup Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
if [ ! -d /data/ssh ]; then
mkdir -p /data/ssh
fi
if [ ! -f /data/ssh/ssh_host_ed25519_key ]; then
echo "Generating /data/ssh/ssh_host_ed25519_key..."
ssh-keygen -t ed25519 -b 4096 -f /data/ssh/ssh_host_ed25519_key -N "" > /dev/null
fi
if [ ! -f /data/ssh/ssh_host_rsa_key ]; then
echo "Generating /data/ssh/ssh_host_rsa_key..."
ssh-keygen -t rsa -b 2048 -f /data/ssh/ssh_host_rsa_key -N "" > /dev/null
fi
if [ ! -f /data/ssh/ssh_host_dsa_key ]; then
echo "Generating /data/ssh/ssh_host_dsa_key..."
ssh-keygen -t dsa -f /data/ssh/ssh_host_dsa_key -N "" > /dev/null
fi
if [ ! -f /data/ssh/ssh_host_ecdsa_key ]; then
echo "Generating /data/ssh/ssh_host_ecdsa_key..."
ssh-keygen -t ecdsa -b 256 -f /data/ssh/ssh_host_ecdsa_key -N "" > /dev/null
fi
chown root:root /data/ssh/*
chmod 0700 /data/ssh
chmod 0600 /data/ssh/*

2
docker/etc/s6/syslogd/finish Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
exit 0

6
docker/etc/s6/syslogd/run Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/bash
[[ -f ./setup ]] && source ./setup
pushd /root > /dev/null
exec su-exec root /sbin/syslogd -nS -O-
popd

1
docker/etc/s6/syslogd/setup Executable file
View File

@@ -0,0 +1 @@
#!/bin/bash

View File

@@ -1,16 +1,33 @@
Port 22
Protocol 2
AddressFamily any
ListenAddress 0.0.0.0
ListenAddress ::
Protocol 2
LogLevel INFO
HostKey /data/ssh/ssh_host_ed25519_key
HostKey /data/ssh/ssh_host_rsa_key
HostKey /data/ssh/ssh_host_dsa_key
HostKey /data/ssh/ssh_host_ecdsa_key
HostKey /data/ssh/ssh_host_ed25519_key
PermitRootLogin no
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no
UsePrivilegeSeparation no
AuthorizedKeysFile .ssh/authorized_keys
UseDNS no
AllowAgentForwarding no
AllowTcpForwarding no
PrintMotd no
PrintLastLog no
PermitUserEnvironment yes
PermitRootLogin no
ChallengeResponseAuthentication no
PasswordAuthentication no
PermitEmptyPasswords no
AllowUsers git
Banner none
Subsystem sftp /usr/lib/ssh/sftp-server
UsePrivilegeSeparation no

View File

@@ -0,0 +1,24 @@
[repository]
ROOT = /data/git/repositories
[repository.upload]
TEMP_PATH = /data/gitea/uploads
[server]
APP_DATA_PATH = /data/gitea
[database]
HOST = mysql:3306
PATH = /data/gitea/gitea.db
[session]
PROVIDER_CONFIG = /data/gitea/sessions
[picture]
AVATAR_UPLOAD_PATH = /data/gitea/avatars
[attachment]
PATH = /data/gitea/attachments
[log]
ROOT_PATH = /data/gitea/log

View File

@@ -1,5 +0,0 @@
#!/bin/sh
# Cleanup SOCAT services and s6 event folder
rm -rf $(find /app/gogs/docker/s6/ -name 'event')
rm -rf /app/gogs/docker/s6/SOCAT_*

View File

View File

@@ -1,9 +0,0 @@
#!/bin/sh
# Crontabs are located by default in /var/spool/cron/crontabs/
# The default configuration is also calling all the scripts in /etc/periodic/${period}
if test -f ./setup; then
source ./setup
fi
exec gosu root /usr/sbin/crond -fS

View File

@@ -1,8 +0,0 @@
#!/bin/sh
if test -f ./setup; then
source ./setup
fi
export USER=git
exec gosu $USER /app/gogs/gogs web

View File

@@ -1,23 +0,0 @@
#!/bin/sh
if ! test -d ~git/.ssh; then
mkdir -p ~git/.ssh
chmod 700 ~git/.ssh
fi
if ! test -f ~git/.ssh/environment; then
echo "GITEA_CUSTOM=${GITEA_CUSTOM}" > ~git/.ssh/environment
chmod 600 ~git/.ssh/environment
fi
cd /app/gogs
# Link volumed data with app data
ln -sf /data/gogs/log ./log
ln -sf /data/gogs/data ./data
# Backward Compatibility with Gogs Container v0.6.15
ln -sf /data/git /home/git
chown -R git:git /data /app/gogs ~git/
chmod 0755 /data /data/gogs ~git/

View File

@@ -1,7 +0,0 @@
#!/bin/sh
if test -f ./setup; then
source ./setup
fi
exec gosu root /usr/sbin/sshd -D -f /app/gogs/docker/sshd_config

View File

@@ -1,23 +0,0 @@
#!/bin/sh
# Check if host keys are present, else create them
if ! test -f /data/ssh/ssh_host_rsa_key; then
ssh-keygen -q -f /data/ssh/ssh_host_rsa_key -N '' -t rsa
fi
if ! test -f /data/ssh/ssh_host_dsa_key; then
ssh-keygen -q -f /data/ssh/ssh_host_dsa_key -N '' -t dsa
fi
if ! test -f /data/ssh/ssh_host_ecdsa_key; then
ssh-keygen -q -f /data/ssh/ssh_host_ecdsa_key -N '' -t ecdsa
fi
if ! test -f /data/ssh/ssh_host_ed25519_key; then
ssh-keygen -q -f /data/ssh/ssh_host_ed25519_key -N '' -t ed25519
fi
# Set correct right to ssh keys
chown -R root:root /data/ssh/*
chmod 0700 /data/ssh
chmod 0600 /data/ssh/*

View File

@@ -1,7 +0,0 @@
#!/bin/sh
if test -f ./setup; then
source ./setup
fi
exec gosu root /sbin/syslogd -nS -O-

View File

@@ -1,65 +0,0 @@
#!/bin/sh
create_socat_links() {
# Bind linked docker container to localhost socket using socat
USED_PORT="3000:22"
while read NAME ADDR PORT; do
if test -z "$NAME$ADDR$PORT"; then
continue
elif echo $USED_PORT | grep -E "(^|:)$PORT($|:)" > /dev/null; then
echo "init:socat | Can't bind linked container ${NAME} to localhost, port ${PORT} already in use" 1>&2
else
SERV_FOLDER=/app/gogs/docker/s6/SOCAT_${NAME}_${PORT}
mkdir -p ${SERV_FOLDER}
CMD="socat -ls TCP4-LISTEN:${PORT},fork,reuseaddr TCP4:${ADDR}:${PORT}"
echo -e "#!/bin/sh\nexec $CMD" > ${SERV_FOLDER}/run
chmod +x ${SERV_FOLDER}/run
USED_PORT="${USED_PORT}:${PORT}"
echo "init:socat | Linked container ${NAME} will be binded to localhost on port ${PORT}" 1>&2
fi
done << EOT
$(env | sed -En 's|(.*)_PORT_([0-9]+)_TCP=tcp://(.*):([0-9]+)|\1 \3 \4|p')
EOT
}
cleanup() {
# Cleanup SOCAT services and s6 event folder
# On start and on shutdown in case container has been killed
rm -rf $(find /app/gogs/docker/s6/ -name 'event')
rm -rf /app/gogs/docker/s6/SOCAT_*
}
create_volume_subfolder() {
# Create VOLUME subfolder
for f in /data/gogs/data /data/gogs/conf /data/gogs/log /data/git /data/ssh; do
if ! test -d $f; then
mkdir -p $f
fi
done
}
cleanup
create_volume_subfolder
LINK=$(echo "$SOCAT_LINK" | tr '[:upper:]' '[:lower:]')
if [ "$LINK" = "false" -o "$LINK" = "0" ]; then
echo "init:socat | Will not try to create socat links as requested" 1>&2
else
create_socat_links
fi
CROND=$(echo "$RUN_CROND" | tr '[:upper:]' '[:lower:]')
if [ "$CROND" = "true" -o "$CROND" = "1" ]; then
echo "init:crond | Cron Daemon (crond) will be run as requested by s6" 1>&2
rm -f /app/gogs/docker/s6/crond/down
else
# Tell s6 not to run the crond service
touch /app/gogs/docker/s6/crond/down
fi
# Exec CMD or S6 by default if nothing present
if [ $# -gt 0 ];then
exec "$@"
else
exec /bin/s6-svscan /app/gogs/docker/s6/
fi

11
docker/usr/bin/entrypoint Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
for FOLDER in /data/gitea/conf /data/gitea/log /data/git /data/ssh; do
mkdir -p ${FOLDER}
done
if [ $# -gt 0 ]; then
exec "$@"
else
exec /bin/s6-svscan /etc/s6
fi

View File

@@ -7,10 +7,11 @@
package main // import "code.gitea.io/gitea"
import (
"log"
"os"
"runtime"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/cmd"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli"
@@ -38,5 +39,9 @@ func main() {
cmd.CmdAdmin,
}
app.Flags = append(app.Flags, []cli.Flag{}...)
log.Fatal(app.Run(os.Args))
err := app.Run(os.Args)
if err != nil {
log.Fatal(4, "Fail to run app with %s: %v", os.Args, err)
}
}

View File

@@ -10,14 +10,20 @@ import (
"code.gitea.io/gitea/modules/log"
)
// AccessMode specifies the users access mode
type AccessMode int
const (
AccessModeNone AccessMode = iota // 0
AccessModeRead // 1
AccessModeWrite // 2
AccessModeAdmin // 3
AccessModeOwner // 4
// AccessModeNone no access
AccessModeNone AccessMode = iota // 0
// AccessModeRead read access
AccessModeRead // 1
// AccessModeWrite write access
AccessModeWrite // 2
// AccessModeAdmin admin access
AccessModeAdmin // 3
// AccessModeOwner owner access
AccessModeOwner // 4
)
func (mode AccessMode) String() string {
@@ -57,21 +63,21 @@ type Access struct {
Mode AccessMode
}
func accessLevel(e Engine, u *User, repo *Repository) (AccessMode, error) {
func accessLevel(e Engine, user *User, repo *Repository) (AccessMode, error) {
mode := AccessModeNone
if !repo.IsPrivate {
mode = AccessModeRead
}
if u == nil {
if user == nil {
return mode, nil
}
if u.ID == repo.OwnerID {
if user.ID == repo.OwnerID {
return AccessModeOwner, nil
}
a := &Access{UserID: u.ID, RepoID: repo.ID}
a := &Access{UserID: user.ID, RepoID: repo.ID}
if has, err := e.Get(a); !has || err != nil {
return mode, err
}
@@ -80,24 +86,24 @@ func accessLevel(e Engine, u *User, repo *Repository) (AccessMode, error) {
// AccessLevel returns the Access a user has to a repository. Will return NoneAccess if the
// user does not have access. User can be nil!
func AccessLevel(u *User, repo *Repository) (AccessMode, error) {
return accessLevel(x, u, repo)
func AccessLevel(user *User, repo *Repository) (AccessMode, error) {
return accessLevel(x, user, repo)
}
func hasAccess(e Engine, u *User, repo *Repository, testMode AccessMode) (bool, error) {
mode, err := accessLevel(e, u, repo)
func hasAccess(e Engine, user *User, repo *Repository, testMode AccessMode) (bool, error) {
mode, err := accessLevel(e, user, repo)
return testMode <= mode, err
}
// HasAccess returns true if someone has the request access level. User can be nil!
func HasAccess(u *User, repo *Repository, testMode AccessMode) (bool, error) {
return hasAccess(x, u, repo, testMode)
func HasAccess(user *User, repo *Repository, testMode AccessMode) (bool, error) {
return hasAccess(x, user, repo, testMode)
}
// GetRepositoryAccesses finds all repositories with their access mode where a user has access but does not own.
func (u *User) GetRepositoryAccesses() (map[*Repository]AccessMode, error) {
func (user *User) GetRepositoryAccesses() (map[*Repository]AccessMode, error) {
accesses := make([]*Access, 0, 10)
if err := x.Find(&accesses, &Access{UserID: u.ID}); err != nil {
if err := x.Find(&accesses, &Access{UserID: user.ID}); err != nil {
return nil, err
}
@@ -113,7 +119,7 @@ func (u *User) GetRepositoryAccesses() (map[*Repository]AccessMode, error) {
}
if err = repo.GetOwner(); err != nil {
return nil, err
} else if repo.OwnerID == u.ID {
} else if repo.OwnerID == user.ID {
continue
}
repos[repo] = access.Mode
@@ -245,6 +251,6 @@ func (repo *Repository) recalculateAccesses(e Engine) error {
}
// RecalculateAccesses recalculates all accesses for repository.
func (r *Repository) RecalculateAccesses() error {
return r.recalculateAccesses(x)
func (repo *Repository) RecalculateAccesses() error {
return repo.recalculateAccesses(x)
}

View File

@@ -24,8 +24,10 @@ import (
"code.gitea.io/gitea/modules/setting"
)
// ActionType represents the type of an action.
type ActionType int
// Possible action types.
const (
ActionCreateRepo ActionType = iota + 1 // 1
ActionRenameRepo // 2
@@ -45,12 +47,13 @@ const (
)
var (
// Same as Github. See https://help.github.com/articles/closing-issues-via-commit-messages
IssueCloseKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
IssueReopenKeywords = []string{"reopen", "reopens", "reopened"}
// Same as Github. See
// https://help.github.com/articles/closing-issues-via-commit-messages
issueCloseKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
issueReopenKeywords = []string{"reopen", "reopens", "reopened"}
IssueCloseKeywordsPat, IssueReopenKeywordsPat *regexp.Regexp
IssueReferenceKeywordsPat *regexp.Regexp
issueCloseKeywordsPat, issueReopenKeywordsPat *regexp.Regexp
issueReferenceKeywordsPat *regexp.Regexp
)
func assembleKeywordsPattern(words []string) string {
@@ -58,13 +61,14 @@ func assembleKeywordsPattern(words []string) string {
}
func init() {
IssueCloseKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(IssueCloseKeywords))
IssueReopenKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(IssueReopenKeywords))
IssueReferenceKeywordsPat = regexp.MustCompile(`(?i)(?:)(^| )\S+`)
issueCloseKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(issueCloseKeywords))
issueReopenKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(issueReopenKeywords))
issueReferenceKeywordsPat = regexp.MustCompile(`(?i)(?:)(^| )\S+`)
}
// Action represents user operation type and other information to repository.,
// it implemented interface base.Actioner so that can be used in template render.
// Action represents user operation type and other information to
// repository. It implemented interface base.Actioner so that can be
// used in template render.
type Action struct {
ID int64 `xorm:"pk autoincr"`
UserID int64 // Receiver user id.
@@ -82,10 +86,13 @@ type Action struct {
CreatedUnix int64
}
// BeforeInsert will be invoked by XORM before inserting a record
// representing this object.
func (a *Action) BeforeInsert() {
a.CreatedUnix = time.Now().Unix()
}
// AfterSet updates the webhook object upon setting a column.
func (a *Action) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created_unix":
@@ -93,65 +100,87 @@ func (a *Action) AfterSet(colName string, _ xorm.Cell) {
}
}
// GetOpType gets the ActionType of this action.
// TODO: change return type to ActionType ?
func (a *Action) GetOpType() int {
return int(a.OpType)
}
// GetActUserName gets the action's user name.
func (a *Action) GetActUserName() string {
return a.ActUserName
}
// ShortActUserName gets the action's user name trimmed to max 20
// chars.
func (a *Action) ShortActUserName() string {
return base.EllipsisString(a.ActUserName, 20)
}
// GetRepoUserName returns the name of the action repository owner.
func (a *Action) GetRepoUserName() string {
return a.RepoUserName
}
// ShortRepoUserName returns the name of the action repository owner
// trimmed to max 20 chars.
func (a *Action) ShortRepoUserName() string {
return base.EllipsisString(a.RepoUserName, 20)
}
// GetRepoName returns the name of the action repository.
func (a *Action) GetRepoName() string {
return a.RepoName
}
// ShortRepoName returns the name of the action repository
// trimmed to max 33 chars.
func (a *Action) ShortRepoName() string {
return base.EllipsisString(a.RepoName, 33)
}
// GetRepoPath returns the virtual path to the action repository.
func (a *Action) GetRepoPath() string {
return path.Join(a.RepoUserName, a.RepoName)
}
// ShortRepoPath returns the virtual path to the action repository
// trimed to max 20 + 1 + 33 chars.
func (a *Action) ShortRepoPath() string {
return path.Join(a.ShortRepoUserName(), a.ShortRepoName())
}
// GetRepoLink returns relative link to action repository.
func (a *Action) GetRepoLink() string {
if len(setting.AppSubUrl) > 0 {
return path.Join(setting.AppSubUrl, a.GetRepoPath())
if len(setting.AppSubURL) > 0 {
return path.Join(setting.AppSubURL, a.GetRepoPath())
}
return "/" + a.GetRepoPath()
}
// GetBranch returns the action's repository branch.
func (a *Action) GetBranch() string {
return a.RefName
}
// GetContent returns the action's content.
func (a *Action) GetContent() string {
return a.Content
}
// GetCreate returns the action creation time.
func (a *Action) GetCreate() time.Time {
return a.Created
}
// GetIssueInfos returns a list of issues associated with
// the action.
func (a *Action) GetIssueInfos() []string {
return strings.SplitN(a.Content, "|", 2)
}
// GetIssueTitle returns the title of first issue associated
// with the action.
func (a *Action) GetIssueTitle() string {
index := com.StrTo(a.GetIssueInfos()[0]).MustInt64()
issue, err := GetIssueByIndex(a.RepoID, index)
@@ -162,6 +191,8 @@ func (a *Action) GetIssueTitle() string {
return issue.Title
}
// GetIssueContent returns the content of first issue associated with
// this action.
func (a *Action) GetIssueContent() string {
index := com.StrTo(a.GetIssueInfos()[0]).MustInt64()
issue, err := GetIssueByIndex(a.RepoID, index)
@@ -221,6 +252,7 @@ func issueIndexTrimRight(c rune) bool {
return !unicode.IsDigit(c)
}
// PushCommit represents a commit in a push operation.
type PushCommit struct {
Sha1 string
Message string
@@ -231,6 +263,7 @@ type PushCommit struct {
Timestamp time.Time
}
// PushCommits represents list of commits in a push operation.
type PushCommits struct {
Len int
Commits []*PushCommit
@@ -239,13 +272,16 @@ type PushCommits struct {
avatars map[string]string
}
// NewPushCommits creates a new PushCommits object.
func NewPushCommits() *PushCommits {
return &PushCommits{
avatars: make(map[string]string),
}
}
func (pc *PushCommits) ToApiPayloadCommits(repoLink string) []*api.PayloadCommit {
// ToAPIPayloadCommits converts a PushCommits object to
// api.PayloadCommit format.
func (pc *PushCommits) ToAPIPayloadCommits(repoLink string) []*api.PayloadCommit {
commits := make([]*api.PayloadCommit, len(pc.Commits))
for i, commit := range pc.Commits {
authorUsername := ""
@@ -281,21 +317,21 @@ func (pc *PushCommits) ToApiPayloadCommits(repoLink string) []*api.PayloadCommit
// AvatarLink tries to match user in database with e-mail
// in order to show custom avatar, and falls back to general avatar link.
func (push *PushCommits) AvatarLink(email string) string {
_, ok := push.avatars[email]
func (pc *PushCommits) AvatarLink(email string) string {
_, ok := pc.avatars[email]
if !ok {
u, err := GetUserByEmail(email)
if err != nil {
push.avatars[email] = base.AvatarLink(email)
pc.avatars[email] = base.AvatarLink(email)
if !IsErrUserNotExist(err) {
log.Error(4, "GetUserByEmail: %v", err)
}
} else {
push.avatars[email] = u.RelAvatarLink()
pc.avatars[email] = u.RelAvatarLink()
}
}
return push.avatars[email]
return pc.avatars[email]
}
// UpdateIssuesCommit checks if issues are manipulated by commit message.
@@ -305,7 +341,7 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
c := commits[i]
refMarked := make(map[int64]bool)
for _, ref := range IssueReferenceKeywordsPat.FindAllString(c.Message, -1) {
for _, ref := range issueReferenceKeywordsPat.FindAllString(c.Message, -1) {
ref = ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, issueIndexTrimRight)
@@ -343,7 +379,7 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
refMarked = make(map[int64]bool)
// FIXME: can merge this one and next one to a common function.
for _, ref := range IssueCloseKeywordsPat.FindAllString(c.Message, -1) {
for _, ref := range issueCloseKeywordsPat.FindAllString(c.Message, -1) {
ref = ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, issueIndexTrimRight)
@@ -383,7 +419,7 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
}
// It is conflict to have close and reopen at same time, so refsMarkd doesn't need to reinit here.
for _, ref := range IssueReopenKeywordsPat.FindAllString(c.Message, -1) {
for _, ref := range issueReopenKeywordsPat.FindAllString(c.Message, -1) {
ref = ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, issueIndexTrimRight)
@@ -425,6 +461,7 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
return nil
}
// CommitRepoActionOptions represent options of a new commit action.
type CommitRepoActionOptions struct {
PusherName string
RepoOwnerID int64
@@ -435,7 +472,8 @@ type CommitRepoActionOptions struct {
Commits *PushCommits
}
// CommitRepoAction adds new commit actio to the repository, and prepare corresponding webhooks.
// CommitRepoAction adds new commit action to the repository, and prepare
// corresponding webhooks.
func CommitRepoAction(opts CommitRepoActionOptions) error {
pusher, err := GetUserByName(opts.PusherName)
if err != nil {
@@ -501,15 +539,17 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
}()
apiPusher := pusher.APIFormat()
apiRepo := repo.APIFormat(nil)
apiRepo := repo.APIFormat(AccessModeNone)
var shaSum string
switch opType {
case ActionCommitRepo: // Push
if err = PrepareWebhooks(repo, HookEventPush, &api.PushPayload{
Ref: opts.RefFullName,
Before: opts.OldCommitID,
After: opts.NewCommitID,
CompareURL: setting.AppUrl + opts.Commits.CompareURL,
Commits: opts.Commits.ToApiPayloadCommits(repo.HTMLURL()),
CompareURL: setting.AppURL + opts.Commits.CompareURL,
Commits: opts.Commits.ToAPIPayloadCommits(repo.HTMLURL()),
Repo: apiRepo,
Pusher: apiPusher,
Sender: apiPusher,
@@ -518,8 +558,17 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
}
if isNewBranch {
gitRepo, err := git.OpenRepository(repo.RepoPath())
if err != nil {
log.Error(4, "OpenRepository[%s]: %v", repo.RepoPath(), err)
}
shaSum, err = gitRepo.GetBranchCommitID(opts.RefFullName)
if err != nil {
log.Error(4, "GetBranchCommitID[%s]: %v", opts.RefFullName, err)
}
return PrepareWebhooks(repo, HookEventCreate, &api.CreatePayload{
Ref: refName,
Sha: shaSum,
RefType: "branch",
Repo: apiRepo,
Sender: apiPusher,
@@ -527,8 +576,17 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
}
case ActionPushTag: // Create
gitRepo, err := git.OpenRepository(repo.RepoPath())
if err != nil {
log.Error(4, "OpenRepository[%s]: %v", repo.RepoPath(), err)
}
shaSum, err = gitRepo.GetTagCommitID(opts.RefFullName)
if err != nil {
log.Error(4, "GetTagCommitID[%s]: %v", opts.RefFullName, err)
}
return PrepareWebhooks(repo, HookEventCreate, &api.CreatePayload{
Ref: refName,
Sha: shaSum,
RefType: "tag",
Repo: apiRepo,
Sender: apiPusher,

View File

@@ -14,14 +14,15 @@ import (
"github.com/Unknwon/com"
"github.com/go-xorm/xorm"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)
//NoticeType describes the notice type
type NoticeType int
const (
//NoticeRepository type
NoticeRepository NoticeType = iota + 1
)
@@ -34,10 +35,12 @@ type Notice struct {
CreatedUnix int64
}
// BeforeInsert is invoked from XORM before inserting an object of this type.
func (n *Notice) BeforeInsert() {
n.CreatedUnix = time.Now().Unix()
}
// AfterSet is invoked from XORM after setting the value of a field of this object.
func (n *Notice) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created_unix":
@@ -131,7 +134,7 @@ func DeleteNoticesByIDs(ids []int64) error {
return nil
}
_, err := x.
Where("id IN (" + strings.Join(base.Int64sToStrings(ids), ",") + ")").
In("id", ids).
Delete(new(Notice))
return err
}

View File

@@ -8,10 +8,12 @@ import (
"fmt"
)
// ErrNameReserved represents a "reserved name" error.
type ErrNameReserved struct {
Name string
}
// IsErrNameReserved checks if an error is a ErrNameReserved.
func IsErrNameReserved(err error) bool {
_, ok := err.(ErrNameReserved)
return ok
@@ -21,10 +23,13 @@ func (err ErrNameReserved) Error() string {
return fmt.Sprintf("name is reserved [name: %s]", err.Name)
}
// ErrNamePatternNotAllowed represents a "pattern not allowed" error.
type ErrNamePatternNotAllowed struct {
Pattern string
}
// IsErrNamePatternNotAllowed checks if an error is an
// ErrNamePatternNotAllowed.
func IsErrNamePatternNotAllowed(err error) bool {
_, ok := err.(ErrNamePatternNotAllowed)
return ok
@@ -41,10 +46,12 @@ func (err ErrNamePatternNotAllowed) Error() string {
// |______//____ >\___ >__|
// \/ \/
// ErrUserAlreadyExist represents a "user already exists" error.
type ErrUserAlreadyExist struct {
Name string
}
// IsErrUserAlreadyExist checks if an error is a ErrUserAlreadyExists.
func IsErrUserAlreadyExist(err error) bool {
_, ok := err.(ErrUserAlreadyExist)
return ok
@@ -54,24 +61,29 @@ func (err ErrUserAlreadyExist) Error() string {
return fmt.Sprintf("user already exists [name: %s]", err.Name)
}
// ErrUserNotExist represents a "UserNotExist" kind of error.
type ErrUserNotExist struct {
UID int64
Name string
UID int64
Name string
KeyID int64
}
// IsErrUserNotExist checks if an error is a ErrUserNotExist.
func IsErrUserNotExist(err error) bool {
_, ok := err.(ErrUserNotExist)
return ok
}
func (err ErrUserNotExist) Error() string {
return fmt.Sprintf("user does not exist [uid: %d, name: %s]", err.UID, err.Name)
return fmt.Sprintf("user does not exist [uid: %d, name: %s, keyid: %d]", err.UID, err.Name, err.KeyID)
}
// ErrEmailAlreadyUsed represents a "EmailAlreadyUsed" kind of error.
type ErrEmailAlreadyUsed struct {
Email string
}
// IsErrEmailAlreadyUsed checks if an error is a ErrEmailAlreadyUsed.
func IsErrEmailAlreadyUsed(err error) bool {
_, ok := err.(ErrEmailAlreadyUsed)
return ok
@@ -81,10 +93,12 @@ func (err ErrEmailAlreadyUsed) Error() string {
return fmt.Sprintf("e-mail has been used [email: %s]", err.Email)
}
// ErrUserOwnRepos represents a "UserOwnRepos" kind of error.
type ErrUserOwnRepos struct {
UID int64
}
// IsErrUserOwnRepos checks if an error is a ErrUserOwnRepos.
func IsErrUserOwnRepos(err error) bool {
_, ok := err.(ErrUserOwnRepos)
return ok
@@ -94,10 +108,12 @@ func (err ErrUserOwnRepos) Error() string {
return fmt.Sprintf("user still has ownership of repositories [uid: %d]", err.UID)
}
// ErrUserHasOrgs represents a "UserHasOrgs" kind of error.
type ErrUserHasOrgs struct {
UID int64
}
// IsErrUserHasOrgs checks if an error is a ErrUserHasOrgs.
func IsErrUserHasOrgs(err error) bool {
_, ok := err.(ErrUserHasOrgs)
return ok
@@ -107,10 +123,12 @@ func (err ErrUserHasOrgs) Error() string {
return fmt.Sprintf("user still has membership of organizations [uid: %d]", err.UID)
}
// ErrReachLimitOfRepo represents a "ReachLimitOfRepo" kind of error.
type ErrReachLimitOfRepo struct {
Limit int
}
// IsErrReachLimitOfRepo checks if an error is a ErrReachLimitOfRepo.
func IsErrReachLimitOfRepo(err error) bool {
_, ok := err.(ErrReachLimitOfRepo)
return ok
@@ -127,10 +145,12 @@ func (err ErrReachLimitOfRepo) Error() string {
// \__/\ / |__|__|_ \__|
// \/ \/
// ErrWikiAlreadyExist represents a "WikiAlreadyExist" kind of error.
type ErrWikiAlreadyExist struct {
Title string
}
// IsErrWikiAlreadyExist checks if an error is a ErrWikiAlreadyExist.
func IsErrWikiAlreadyExist(err error) bool {
_, ok := err.(ErrWikiAlreadyExist)
return ok
@@ -147,10 +167,12 @@ func (err ErrWikiAlreadyExist) Error() string {
// |____| |____/|___ /____/__|\___ > |____|__ \___ > ____|
// \/ \/ \/ \/\/
// ErrKeyUnableVerify represents a "KeyUnableVerify" kind of error.
type ErrKeyUnableVerify struct {
Result string
}
// IsErrKeyUnableVerify checks if an error is a ErrKeyUnableVerify.
func IsErrKeyUnableVerify(err error) bool {
_, ok := err.(ErrKeyUnableVerify)
return ok
@@ -160,10 +182,12 @@ func (err ErrKeyUnableVerify) Error() string {
return fmt.Sprintf("Unable to verify key content [result: %s]", err.Result)
}
// ErrKeyNotExist represents a "KeyNotExist" kind of error.
type ErrKeyNotExist struct {
ID int64
}
// IsErrKeyNotExist checks if an error is a ErrKeyNotExist.
func IsErrKeyNotExist(err error) bool {
_, ok := err.(ErrKeyNotExist)
return ok
@@ -173,11 +197,13 @@ func (err ErrKeyNotExist) Error() string {
return fmt.Sprintf("public key does not exist [id: %d]", err.ID)
}
// ErrKeyAlreadyExist represents a "KeyAlreadyExist" kind of error.
type ErrKeyAlreadyExist struct {
OwnerID int64
Content string
}
// IsErrKeyAlreadyExist checks if an error is a ErrKeyAlreadyExist.
func IsErrKeyAlreadyExist(err error) bool {
_, ok := err.(ErrKeyAlreadyExist)
return ok
@@ -187,11 +213,13 @@ func (err ErrKeyAlreadyExist) Error() string {
return fmt.Sprintf("public key already exists [owner_id: %d, content: %s]", err.OwnerID, err.Content)
}
// ErrKeyNameAlreadyUsed represents a "KeyNameAlreadyUsed" kind of error.
type ErrKeyNameAlreadyUsed struct {
OwnerID int64
Name string
}
// IsErrKeyNameAlreadyUsed checks if an error is a ErrKeyNameAlreadyUsed.
func IsErrKeyNameAlreadyUsed(err error) bool {
_, ok := err.(ErrKeyNameAlreadyUsed)
return ok
@@ -201,12 +229,14 @@ func (err ErrKeyNameAlreadyUsed) Error() string {
return fmt.Sprintf("public key already exists [owner_id: %d, name: %s]", err.OwnerID, err.Name)
}
// ErrKeyAccessDenied represents a "KeyAccessDenied" kind of error.
type ErrKeyAccessDenied struct {
UserID int64
KeyID int64
Note string
}
// IsErrKeyAccessDenied checks if an error is a ErrKeyAccessDenied.
func IsErrKeyAccessDenied(err error) bool {
_, ok := err.(ErrKeyAccessDenied)
return ok
@@ -217,12 +247,14 @@ func (err ErrKeyAccessDenied) Error() string {
err.UserID, err.KeyID, err.Note)
}
// ErrDeployKeyNotExist represents a "DeployKeyNotExist" kind of error.
type ErrDeployKeyNotExist struct {
ID int64
KeyID int64
RepoID int64
}
// IsErrDeployKeyNotExist checks if an error is a ErrDeployKeyNotExist.
func IsErrDeployKeyNotExist(err error) bool {
_, ok := err.(ErrDeployKeyNotExist)
return ok
@@ -232,11 +264,13 @@ func (err ErrDeployKeyNotExist) Error() string {
return fmt.Sprintf("Deploy key does not exist [id: %d, key_id: %d, repo_id: %d]", err.ID, err.KeyID, err.RepoID)
}
// ErrDeployKeyAlreadyExist represents a "DeployKeyAlreadyExist" kind of error.
type ErrDeployKeyAlreadyExist struct {
KeyID int64
RepoID int64
}
// IsErrDeployKeyAlreadyExist checks if an error is a ErrDeployKeyAlreadyExist.
func IsErrDeployKeyAlreadyExist(err error) bool {
_, ok := err.(ErrDeployKeyAlreadyExist)
return ok
@@ -246,11 +280,13 @@ func (err ErrDeployKeyAlreadyExist) Error() string {
return fmt.Sprintf("public key already exists [key_id: %d, repo_id: %d]", err.KeyID, err.RepoID)
}
// ErrDeployKeyNameAlreadyUsed represents a "DeployKeyNameAlreadyUsed" kind of error.
type ErrDeployKeyNameAlreadyUsed struct {
RepoID int64
Name string
}
// IsErrDeployKeyNameAlreadyUsed checks if an error is a ErrDeployKeyNameAlreadyUsed.
func IsErrDeployKeyNameAlreadyUsed(err error) bool {
_, ok := err.(ErrDeployKeyNameAlreadyUsed)
return ok
@@ -267,10 +303,12 @@ func (err ErrDeployKeyNameAlreadyUsed) Error() string {
// \____|__ /\___ >___ >___ >____ >____ > |____| \____/|__|_ \\___ >___| /
// \/ \/ \/ \/ \/ \/ \/ \/ \/
// ErrAccessTokenNotExist represents a "AccessTokenNotExist" kind of error.
type ErrAccessTokenNotExist struct {
SHA string
}
// IsErrAccessTokenNotExist checks if an error is a ErrAccessTokenNotExist.
func IsErrAccessTokenNotExist(err error) bool {
_, ok := err.(ErrAccessTokenNotExist)
return ok
@@ -280,9 +318,11 @@ func (err ErrAccessTokenNotExist) Error() string {
return fmt.Sprintf("access token does not exist [sha: %s]", err.SHA)
}
// ErrAccessTokenEmpty represents a "AccessTokenEmpty" kind of error.
type ErrAccessTokenEmpty struct {
}
// IsErrAccessTokenEmpty checks if an error is a ErrAccessTokenEmpty.
func IsErrAccessTokenEmpty(err error) bool {
_, ok := err.(ErrAccessTokenEmpty)
return ok
@@ -299,10 +339,12 @@ func (err ErrAccessTokenEmpty) Error() string {
// \_______ /__| \___ (____ /___| /__/_____ \(____ /__| |__|\____/|___| /
// \/ /_____/ \/ \/ \/ \/ \/
// ErrLastOrgOwner represents a "LastOrgOwner" kind of error.
type ErrLastOrgOwner struct {
UID int64
}
// IsErrLastOrgOwner checks if an error is a ErrLastOrgOwner.
func IsErrLastOrgOwner(err error) bool {
_, ok := err.(ErrLastOrgOwner)
return ok
@@ -319,12 +361,14 @@ func (err ErrLastOrgOwner) Error() string {
// |____|_ /\___ > __/ \____/____ >__||__| \____/|__| / ____|
// \/ \/|__| \/ \/
// ErrRepoNotExist represents a "RepoNotExist" kind of error.
type ErrRepoNotExist struct {
ID int64
UID int64
Name string
}
// IsErrRepoNotExist checks if an error is a ErrRepoNotExist.
func IsErrRepoNotExist(err error) bool {
_, ok := err.(ErrRepoNotExist)
return ok
@@ -334,11 +378,13 @@ func (err ErrRepoNotExist) Error() string {
return fmt.Sprintf("repository does not exist [id: %d, uid: %d, name: %s]", err.ID, err.UID, err.Name)
}
// ErrRepoAlreadyExist represents a "RepoAlreadyExist" kind of error.
type ErrRepoAlreadyExist struct {
Uname string
Name string
}
// IsErrRepoAlreadyExist checks if an error is a ErrRepoAlreadyExist.
func IsErrRepoAlreadyExist(err error) bool {
_, ok := err.(ErrRepoAlreadyExist)
return ok
@@ -348,12 +394,14 @@ func (err ErrRepoAlreadyExist) Error() string {
return fmt.Sprintf("repository already exists [uname: %s, name: %s]", err.Uname, err.Name)
}
// ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error.
type ErrInvalidCloneAddr struct {
IsURLError bool
IsInvalidPath bool
IsPermissionDenied bool
}
// IsErrInvalidCloneAddr checks if an error is a ErrInvalidCloneAddr.
func IsErrInvalidCloneAddr(err error) bool {
_, ok := err.(ErrInvalidCloneAddr)
return ok
@@ -364,10 +412,12 @@ func (err ErrInvalidCloneAddr) Error() string {
err.IsURLError, err.IsInvalidPath, err.IsPermissionDenied)
}
// ErrUpdateTaskNotExist represents a "UpdateTaskNotExist" kind of error.
type ErrUpdateTaskNotExist struct {
UUID string
}
// IsErrUpdateTaskNotExist checks if an error is a ErrUpdateTaskNotExist.
func IsErrUpdateTaskNotExist(err error) bool {
_, ok := err.(ErrUpdateTaskNotExist)
return ok
@@ -377,10 +427,12 @@ func (err ErrUpdateTaskNotExist) Error() string {
return fmt.Sprintf("update task does not exist [uuid: %s]", err.UUID)
}
// ErrReleaseAlreadyExist represents a "ReleaseAlreadyExist" kind of error.
type ErrReleaseAlreadyExist struct {
TagName string
}
// IsErrReleaseAlreadyExist checks if an error is a ErrReleaseAlreadyExist.
func IsErrReleaseAlreadyExist(err error) bool {
_, ok := err.(ErrReleaseAlreadyExist)
return ok
@@ -390,11 +442,13 @@ func (err ErrReleaseAlreadyExist) Error() string {
return fmt.Sprintf("release tag already exist [tag_name: %s]", err.TagName)
}
// ErrReleaseNotExist represents a "ReleaseNotExist" kind of error.
type ErrReleaseNotExist struct {
ID int64
TagName string
}
// IsErrReleaseNotExist checks if an error is a ErrReleaseNotExist.
func IsErrReleaseNotExist(err error) bool {
_, ok := err.(ErrReleaseNotExist)
return ok
@@ -404,10 +458,12 @@ func (err ErrReleaseNotExist) Error() string {
return fmt.Sprintf("release tag does not exist [id: %d, tag_name: %s]", err.ID, err.TagName)
}
// ErrInvalidTagName represents a "InvalidTagName" kind of error.
type ErrInvalidTagName struct {
TagName string
}
// IsErrInvalidTagName checks if an error is a ErrInvalidTagName.
func IsErrInvalidTagName(err error) bool {
_, ok := err.(ErrInvalidTagName)
return ok
@@ -417,10 +473,12 @@ func (err ErrInvalidTagName) Error() string {
return fmt.Sprintf("release tag name is not valid [tag_name: %s]", err.TagName)
}
// ErrRepoFileAlreadyExist represents a "RepoFileAlreadyExist" kind of error.
type ErrRepoFileAlreadyExist struct {
FileName string
}
// IsErrRepoFileAlreadyExist checks if an error is a ErrRepoFileAlreadyExist.
func IsErrRepoFileAlreadyExist(err error) bool {
_, ok := err.(ErrRepoFileAlreadyExist)
return ok
@@ -437,10 +495,12 @@ func (err ErrRepoFileAlreadyExist) Error() string {
// |______ / |__| (____ /___| /\___ >___| /
// \/ \/ \/ \/ \/
// ErrBranchNotExist represents a "BranchNotExist" kind of error.
type ErrBranchNotExist struct {
Name string
}
// IsErrBranchNotExist checks if an error is a ErrBranchNotExist.
func IsErrBranchNotExist(err error) bool {
_, ok := err.(ErrBranchNotExist)
return ok
@@ -457,10 +517,12 @@ func (err ErrBranchNotExist) Error() string {
// \__/\ / \___ >___ /___| /\____/ \____/|__|_ \
// \/ \/ \/ \/ \/
// ErrWebhookNotExist represents a "WebhookNotExist" kind of error.
type ErrWebhookNotExist struct {
ID int64
}
// IsErrWebhookNotExist checks if an error is a ErrWebhookNotExist.
func IsErrWebhookNotExist(err error) bool {
_, ok := err.(ErrWebhookNotExist)
return ok
@@ -477,12 +539,14 @@ func (err ErrWebhookNotExist) Error() string {
// |___/____ >____ >____/ \___ >
// \/ \/ \/
// ErrIssueNotExist represents a "IssueNotExist" kind of error.
type ErrIssueNotExist struct {
ID int64
RepoID int64
Index int64
}
// IsErrIssueNotExist checks if an error is a ErrIssueNotExist.
func IsErrIssueNotExist(err error) bool {
_, ok := err.(ErrIssueNotExist)
return ok
@@ -499,6 +563,7 @@ func (err ErrIssueNotExist) Error() string {
// |____| |____/|____/____/____|_ /\___ >__ |____/ \___ >____ > |__|
// \/ \/ |__| \/ \/
// ErrPullRequestNotExist represents a "PullRequestNotExist" kind of error.
type ErrPullRequestNotExist struct {
ID int64
IssueID int64
@@ -508,6 +573,7 @@ type ErrPullRequestNotExist struct {
BaseBranch string
}
// IsErrPullRequestNotExist checks if an error is a ErrPullRequestNotExist.
func IsErrPullRequestNotExist(err error) bool {
_, ok := err.(ErrPullRequestNotExist)
return ok
@@ -518,6 +584,28 @@ func (err ErrPullRequestNotExist) Error() string {
err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBarcnh, err.BaseBranch)
}
// ErrPullRequestAlreadyExists represents a "PullRequestAlreadyExists"-error
type ErrPullRequestAlreadyExists struct {
ID int64
IssueID int64
HeadRepoID int64
BaseRepoID int64
HeadBranch string
BaseBranch string
}
// IsErrPullRequestAlreadyExists checks if an error is a ErrPullRequestAlreadyExists.
func IsErrPullRequestAlreadyExists(err error) bool {
_, ok := err.(ErrPullRequestAlreadyExists)
return ok
}
// Error does pretty-printing :D
func (err ErrPullRequestAlreadyExists) Error() string {
return fmt.Sprintf("pull request already exists for these targets [id: %d, issue_id: %d, head_repo_id: %d, base_repo_id: %d, head_branch: %s, base_branch: %s]",
err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch)
}
// _________ __
// \_ ___ \ ____ _____ _____ ____ _____/ |_
// / \ \/ / _ \ / \ / \_/ __ \ / \ __\
@@ -525,11 +613,13 @@ func (err ErrPullRequestNotExist) Error() string {
// \______ /\____/|__|_| /__|_| /\___ >___| /__|
// \/ \/ \/ \/ \/
// ErrCommentNotExist represents a "CommentNotExist" kind of error.
type ErrCommentNotExist struct {
ID int64
IssueID int64
}
// IsErrCommentNotExist checks if an error is a ErrCommentNotExist.
func IsErrCommentNotExist(err error) bool {
_, ok := err.(ErrCommentNotExist)
return ok
@@ -546,11 +636,13 @@ func (err ErrCommentNotExist) Error() string {
// |_______ (____ /___ /\___ >____/
// \/ \/ \/ \/
// ErrLabelNotExist represents a "LabelNotExist" kind of error.
type ErrLabelNotExist struct {
LabelID int64
RepoID int64
}
// IsErrLabelNotExist checks if an error is a ErrLabelNotExist.
func IsErrLabelNotExist(err error) bool {
_, ok := err.(ErrLabelNotExist)
return ok
@@ -567,11 +659,13 @@ func (err ErrLabelNotExist) Error() string {
// \____|__ /__|____/\___ >____ > |__| \____/|___| /\___ >
// \/ \/ \/ \/ \/
// ErrMilestoneNotExist represents a "MilestoneNotExist" kind of error.
type ErrMilestoneNotExist struct {
ID int64
RepoID int64
}
// IsErrMilestoneNotExist checks if an error is a ErrMilestoneNotExist.
func IsErrMilestoneNotExist(err error) bool {
_, ok := err.(ErrMilestoneNotExist)
return ok
@@ -588,11 +682,13 @@ func (err ErrMilestoneNotExist) Error() string {
// \____|__ /__| |__| (____ /\___ >___| /__|_| /\___ >___| /__|
// \/ \/ \/ \/ \/ \/ \/
// ErrAttachmentNotExist represents a "AttachmentNotExist" kind of error.
type ErrAttachmentNotExist struct {
ID int64
UUID string
}
// IsErrAttachmentNotExist checks if an error is a ErrAttachmentNotExist.
func IsErrAttachmentNotExist(err error) bool {
_, ok := err.(ErrAttachmentNotExist)
return ok
@@ -609,10 +705,12 @@ func (err ErrAttachmentNotExist) Error() string {
// |_______ \____/\___ /|__|___| / /_______ /\____/|____/ |__| \___ >___ >
// \/ /_____/ \/ \/ \/ \/
// ErrLoginSourceNotExist represents a "LoginSourceNotExist" kind of error.
type ErrLoginSourceNotExist struct {
ID int64
}
// IsErrLoginSourceNotExist checks if an error is a ErrLoginSourceNotExist.
func IsErrLoginSourceNotExist(err error) bool {
_, ok := err.(ErrLoginSourceNotExist)
return ok
@@ -622,10 +720,12 @@ func (err ErrLoginSourceNotExist) Error() string {
return fmt.Sprintf("login source does not exist [id: %d]", err.ID)
}
// ErrLoginSourceAlreadyExist represents a "LoginSourceAlreadyExist" kind of error.
type ErrLoginSourceAlreadyExist struct {
Name string
}
// IsErrLoginSourceAlreadyExist checks if an error is a ErrLoginSourceAlreadyExist.
func IsErrLoginSourceAlreadyExist(err error) bool {
_, ok := err.(ErrLoginSourceAlreadyExist)
return ok
@@ -635,10 +735,12 @@ func (err ErrLoginSourceAlreadyExist) Error() string {
return fmt.Sprintf("login source already exists [name: %s]", err.Name)
}
// ErrLoginSourceInUse represents a "LoginSourceInUse" kind of error.
type ErrLoginSourceInUse struct {
ID int64
}
// IsErrLoginSourceInUse checks if an error is a ErrLoginSourceInUse.
func IsErrLoginSourceInUse(err error) bool {
_, ok := err.(ErrLoginSourceInUse)
return ok
@@ -655,11 +757,13 @@ func (err ErrLoginSourceInUse) Error() string {
// |____| \___ >____ /__|_| /
// \/ \/ \/
// ErrTeamAlreadyExist represents a "TeamAlreadyExist" kind of error.
type ErrTeamAlreadyExist struct {
OrgID int64
Name string
}
// IsErrTeamAlreadyExist checks if an error is a ErrTeamAlreadyExist.
func IsErrTeamAlreadyExist(err error) bool {
_, ok := err.(ErrTeamAlreadyExist)
return ok
@@ -677,11 +781,13 @@ func (err ErrTeamAlreadyExist) Error() string {
// |__| \/ \/
//
// ErrUploadNotExist represents a "UploadNotExist" kind of error.
type ErrUploadNotExist struct {
ID int64
UUID string
}
// IsErrUploadNotExist checks if an error is a ErrUploadNotExist.
func IsErrUploadNotExist(err error) bool {
_, ok := err.(ErrAttachmentNotExist)
return ok

View File

@@ -18,18 +18,20 @@ import (
"code.gitea.io/git"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/highlight"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/template/highlight"
"github.com/Unknwon/com"
"github.com/sergi/go-diff/diffmatchpatch"
"golang.org/x/net/html/charset"
"golang.org/x/text/transform"
)
// DiffLineType represents the type of a DiffLine.
type DiffLineType uint8
// DiffLineType possible values.
const (
DiffLinePlain DiffLineType = iota + 1
DiffLineAdd
@@ -37,8 +39,10 @@ const (
DiffLineSection
)
// DiffFileType represents the type of a DiffFile.
type DiffFileType uint8
// DiffFileType possible values.
const (
DiffFileAdd DiffFileType = iota + 1
DiffFileChange
@@ -46,6 +50,7 @@ const (
DiffFileRename
)
// DiffLine represents a line difference in a DiffSection.
type DiffLine struct {
LeftIdx int
RightIdx int
@@ -53,10 +58,12 @@ type DiffLine struct {
Content string
}
// GetType returns the type of a DiffLine.
func (d *DiffLine) GetType() int {
return int(d.Type)
}
// DiffSection represents a section of a DiffFile.
type DiffSection struct {
Name string
Lines []*DiffLine
@@ -97,7 +104,7 @@ func diffToHTML(diffs []diffmatchpatch.Diff, lineType DiffLineType) template.HTM
return template.HTML(buf.Bytes())
}
// get an specific line by type (add or del) and file line number
// GetLine gets a specific line by type (add or del) and file line number
func (diffSection *DiffSection) GetLine(lineType DiffLineType, idx int) *DiffLine {
var (
difference = 0
@@ -146,7 +153,7 @@ func init() {
diffMatchPatch.DiffEditCost = 100
}
// computes inline diff for the given line
// GetComputedInlineDiffFor computes inline diff for the given line.
func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine) template.HTML {
if setting.Git.DisableDiffHighlight {
return template.HTML(html.EscapeString(diffLine.Content[1:]))
@@ -183,6 +190,7 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine) tem
return diffToHTML(diffRecord, diffLine.Type)
}
// DiffFile represents a file diff.
type DiffFile struct {
Name string
OldName string
@@ -198,26 +206,32 @@ type DiffFile struct {
IsIncomplete bool
}
// GetType returns type of diff file.
func (diffFile *DiffFile) GetType() int {
return int(diffFile.Type)
}
// GetHighlightClass returns highlight class for a filename.
func (diffFile *DiffFile) GetHighlightClass() string {
return highlight.FileNameToHighlightClass(diffFile.Name)
}
// Diff represents a difference between two git trees.
type Diff struct {
TotalAddition, TotalDeletion int
Files []*DiffFile
IsIncomplete bool
}
// NumFiles returns number of files changes in a diff.
func (diff *Diff) NumFiles() int {
return len(diff.Files)
}
const DIFF_HEAD = "diff --git "
const cmdDiffHead = "diff --git "
// ParsePatch builds a Diff object from a io.Reader and some
// parameters.
// TODO: move this function to gogits/git-module
func ParsePatch(maxLines, maxLineCharacteres, maxFiles int, reader io.Reader) (*Diff, error) {
var (
@@ -307,19 +321,19 @@ func ParsePatch(maxLines, maxLineCharacteres, maxFiles int, reader io.Reader) (*
}
// Get new file.
if strings.HasPrefix(line, DIFF_HEAD) {
if strings.HasPrefix(line, cmdDiffHead) {
middle := -1
// Note: In case file name is surrounded by double quotes (it happens only in git-shell).
// e.g. diff --git "a/xxx" "b/xxx"
hasQuote := line[len(DIFF_HEAD)] == '"'
hasQuote := line[len(cmdDiffHead)] == '"'
if hasQuote {
middle = strings.Index(line, ` "b/`)
} else {
middle = strings.Index(line, " b/")
}
beg := len(DIFF_HEAD)
beg := len(cmdDiffHead)
a := line[beg+2 : middle]
b := line[middle+3:]
if hasQuote {
@@ -405,6 +419,9 @@ func ParsePatch(maxLines, maxLineCharacteres, maxFiles int, reader io.Reader) (*
return diff, nil
}
// GetDiffRange builds a Diff between two commits of a repository.
// passing the empty string as beforeCommitID returns a diff from the
// parent commit.
func GetDiffRange(repoPath, beforeCommitID, afterCommitID string, maxLines, maxLineCharacteres, maxFiles int) (*Diff, error) {
gitRepo, err := git.OpenRepository(repoPath)
if err != nil {
@@ -456,8 +473,10 @@ func GetDiffRange(repoPath, beforeCommitID, afterCommitID string, maxLines, maxL
return diff, nil
}
// RawDiffType type of a raw diff.
type RawDiffType string
// RawDiffType possible values.
const (
RawDiffNormal RawDiffType = "diff"
RawDiffPatch RawDiffType = "patch"
@@ -509,6 +528,7 @@ func GetRawDiff(repoPath, commitID string, diffType RawDiffType, writer io.Write
return nil
}
// GetDiffCommit builds a Diff representing the given commitID.
func GetDiffCommit(repoPath, commitID string, maxLines, maxLineCharacteres, maxFiles int) (*Diff, error) {
return GetDiffRange(repoPath, "", commitID, maxLines, maxLineCharacteres, maxFiles)
}

View File

@@ -25,7 +25,7 @@ import (
)
var (
ErrMissingIssueNumber = errors.New("No issue number specified")
errMissingIssueNumber = errors.New("No issue number specified")
)
// Issue represents an issue or pull request of repository.
@@ -62,16 +62,20 @@ type Issue struct {
Comments []*Comment `xorm:"-"`
}
// BeforeInsert is invoked from XORM before inserting an object of this type.
func (issue *Issue) BeforeInsert() {
issue.CreatedUnix = time.Now().Unix()
issue.UpdatedUnix = issue.CreatedUnix
}
// BeforeUpdate is invoked from XORM before updating this object.
func (issue *Issue) BeforeUpdate() {
issue.UpdatedUnix = time.Now().Unix()
issue.DeadlineUnix = issue.Deadline.Unix()
}
// AfterSet is invoked from XORM after setting the value of a field of
// this object.
func (issue *Issue) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "deadline_unix":
@@ -150,10 +154,12 @@ func (issue *Issue) loadAttributes(e Engine) (err error) {
return nil
}
// LoadAttributes loads the attribute of this issue.
func (issue *Issue) LoadAttributes() error {
return issue.loadAttributes(x)
}
// HTMLURL returns the absolute URL to this issue.
func (issue *Issue) HTMLURL() string {
var path string
if issue.IsPull {
@@ -164,15 +170,31 @@ func (issue *Issue) HTMLURL() string {
return fmt.Sprintf("%s/%s/%d", issue.Repo.HTMLURL(), path, issue.Index)
}
// State returns string representation of issue status.
func (i *Issue) State() api.StateType {
if i.IsClosed {
return api.STATE_CLOSED
// DiffURL returns the absolute URL to this diff
func (issue *Issue) DiffURL() string {
if issue.IsPull {
return fmt.Sprintf("%s/pulls/%d.diff", issue.Repo.HTMLURL(), issue.Index)
}
return api.STATE_OPEN
return ""
}
// This method assumes some fields assigned with values:
// PatchURL returns the absolute URL to this patch
func (issue *Issue) PatchURL() string {
if issue.IsPull {
return fmt.Sprintf("%s/pulls/%d.patch", issue.Repo.HTMLURL(), issue.Index)
}
return ""
}
// State returns string representation of issue status.
func (issue *Issue) State() api.StateType {
if issue.IsClosed {
return api.StateClosed
}
return api.StateOpen
}
// APIFormat assumes some fields assigned with values:
// Required - Poster, Labels,
// Optional - Milestone, Assignee, PullRequest
func (issue *Issue) APIFormat() *api.Issue {
@@ -213,22 +235,22 @@ func (issue *Issue) APIFormat() *api.Issue {
}
// HashTag returns unique hash tag for issue.
func (i *Issue) HashTag() string {
return "issue-" + com.ToStr(i.ID)
func (issue *Issue) HashTag() string {
return "issue-" + com.ToStr(issue.ID)
}
// IsPoster returns true if given user by ID is the poster.
func (i *Issue) IsPoster(uid int64) bool {
return i.PosterID == uid
func (issue *Issue) IsPoster(uid int64) bool {
return issue.PosterID == uid
}
func (i *Issue) hasLabel(e Engine, labelID int64) bool {
return hasIssueLabel(e, i.ID, labelID)
func (issue *Issue) hasLabel(e Engine, labelID int64) bool {
return hasIssueLabel(e, issue.ID, labelID)
}
// HasLabel returns true if issue has been labeled by given ID.
func (i *Issue) HasLabel(labelID int64) bool {
return i.hasLabel(x, labelID)
func (issue *Issue) HasLabel(labelID int64) bool {
return issue.hasLabel(x, labelID)
}
func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
@@ -243,7 +265,7 @@ func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
Action: api.HookIssueLabelUpdated,
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(nil),
Repository: issue.Repo.APIFormat(AccessModeNone),
Sender: doer.APIFormat(),
})
}
@@ -254,8 +276,8 @@ func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
}
}
func (i *Issue) addLabel(e *xorm.Session, label *Label) error {
return newIssueLabel(e, i, label)
func (issue *Issue) addLabel(e *xorm.Session, label *Label) error {
return newIssueLabel(e, issue, label)
}
// AddLabel adds a new label to the issue.
@@ -322,6 +344,8 @@ func (issue *Issue) clearLabels(e *xorm.Session) (err error) {
return nil
}
// ClearLabels removes all issue labels as the given user.
// Triggers appropriate WebHooks, if any.
func (issue *Issue) ClearLabels(doer *User) (err error) {
sess := x.NewSession()
defer sessionRelease(sess)
@@ -347,7 +371,7 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
Action: api.HookIssueLabelCleared,
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(nil),
Repository: issue.Repo.APIFormat(AccessModeNone),
Sender: doer.APIFormat(),
})
}
@@ -361,6 +385,7 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
}
// ReplaceLabels removes all current labels and add new labels to the issue.
// Triggers appropriate WebHooks, if any.
func (issue *Issue) ReplaceLabels(labels []*Label) (err error) {
sess := x.NewSession()
defer sessionRelease(sess)
@@ -377,12 +402,13 @@ func (issue *Issue) ReplaceLabels(labels []*Label) (err error) {
return sess.Commit()
}
func (i *Issue) GetAssignee() (err error) {
if i.AssigneeID == 0 || i.Assignee != nil {
// GetAssignee sets the Assignee attribute of this issue.
func (issue *Issue) GetAssignee() (err error) {
if issue.AssigneeID == 0 || issue.Assignee != nil {
return nil
}
i.Assignee, err = GetUserByID(i.AssigneeID)
issue.Assignee, err = GetUserByID(issue.AssigneeID)
if IsErrUserNotExist(err) {
return nil
}
@@ -390,8 +416,8 @@ func (i *Issue) GetAssignee() (err error) {
}
// ReadBy sets issue to be read by given user.
func (i *Issue) ReadBy(uid int64) error {
return UpdateIssueUserByRead(uid, i.ID)
func (issue *Issue) ReadBy(uid int64) error {
return UpdateIssueUserByRead(uid, issue.ID)
}
func updateIssueCols(e Engine, issue *Issue, cols ...string) error {
@@ -404,41 +430,41 @@ func UpdateIssueCols(issue *Issue, cols ...string) error {
return updateIssueCols(x, issue, cols...)
}
func (i *Issue) changeStatus(e *xorm.Session, doer *User, repo *Repository, isClosed bool) (err error) {
func (issue *Issue) changeStatus(e *xorm.Session, doer *User, repo *Repository, isClosed bool) (err error) {
// Nothing should be performed if current status is same as target status
if i.IsClosed == isClosed {
if issue.IsClosed == isClosed {
return nil
}
i.IsClosed = isClosed
issue.IsClosed = isClosed
if err = updateIssueCols(e, i, "is_closed"); err != nil {
if err = updateIssueCols(e, issue, "is_closed"); err != nil {
return err
} else if err = updateIssueUsersByStatus(e, i.ID, isClosed); err != nil {
} else if err = updateIssueUsersByStatus(e, issue.ID, isClosed); err != nil {
return err
}
// Update issue count of labels
if err = i.getLabels(e); err != nil {
if err = issue.getLabels(e); err != nil {
return err
}
for idx := range i.Labels {
if i.IsClosed {
i.Labels[idx].NumClosedIssues++
for idx := range issue.Labels {
if issue.IsClosed {
issue.Labels[idx].NumClosedIssues++
} else {
i.Labels[idx].NumClosedIssues--
issue.Labels[idx].NumClosedIssues--
}
if err = updateLabel(e, i.Labels[idx]); err != nil {
if err = updateLabel(e, issue.Labels[idx]); err != nil {
return err
}
}
// Update issue count of milestone
if err = changeMilestoneIssueStats(e, i); err != nil {
if err = changeMilestoneIssueStats(e, issue); err != nil {
return err
}
// New action comment
if _, err = createStatusComment(e, doer, repo, i); err != nil {
if _, err = createStatusComment(e, doer, repo, issue); err != nil {
return err
}
@@ -467,13 +493,13 @@ func (issue *Issue) ChangeStatus(doer *User, repo *Repository, isClosed bool) (e
apiPullRequest := &api.PullRequestPayload{
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
Repository: repo.APIFormat(nil),
Repository: repo.APIFormat(AccessModeNone),
Sender: doer.APIFormat(),
}
if isClosed {
apiPullRequest.Action = api.HookIssueClosed
} else {
apiPullRequest.Action = api.HookIssueReopened
apiPullRequest.Action = api.HookIssueReOpened
}
err = PrepareWebhooks(repo, HookEventPullRequest, apiPullRequest)
}
@@ -486,6 +512,7 @@ func (issue *Issue) ChangeStatus(doer *User, repo *Repository, isClosed bool) (e
return nil
}
// ChangeTitle changes the title of this issue, as the given user.
func (issue *Issue) ChangeTitle(doer *User, title string) (err error) {
oldTitle := issue.Title
issue.Title = title
@@ -504,7 +531,7 @@ func (issue *Issue) ChangeTitle(doer *User, title string) (err error) {
},
},
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(nil),
Repository: issue.Repo.APIFormat(AccessModeNone),
Sender: doer.APIFormat(),
})
}
@@ -517,6 +544,7 @@ func (issue *Issue) ChangeTitle(doer *User, title string) (err error) {
return nil
}
// ChangeContent changes issue content, as the given user.
func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
oldContent := issue.Content
issue.Content = content
@@ -535,7 +563,7 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
},
},
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(nil),
Repository: issue.Repo.APIFormat(AccessModeNone),
Sender: doer.APIFormat(),
})
}
@@ -548,6 +576,7 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
return nil
}
// ChangeAssignee changes the Asssignee field of this issue.
func (issue *Issue) ChangeAssignee(doer *User, assigneeID int64) (err error) {
issue.AssigneeID = assigneeID
if err = UpdateIssueUserByAssignee(issue); err != nil {
@@ -567,7 +596,7 @@ func (issue *Issue) ChangeAssignee(doer *User, assigneeID int64) (err error) {
apiPullRequest := &api.PullRequestPayload{
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(nil),
Repository: issue.Repo.APIFormat(AccessModeNone),
Sender: doer.APIFormat(),
}
if isRemoveAssignee {
@@ -586,6 +615,7 @@ func (issue *Issue) ChangeAssignee(doer *User, assigneeID int64) (err error) {
return nil
}
// NewIssueOptions represents the options of a new issue.
type NewIssueOptions struct {
Repo *Repository
Issue *Issue
@@ -650,7 +680,7 @@ func newIssue(e *xorm.Session, opts NewIssueOptions) (err error) {
}
if len(opts.LableIDs) > 0 {
// During the session, SQLite3 dirver cannot handle retrieve objects after update something.
// During the session, SQLite3 driver cannot handle retrieve objects after update something.
// So we have to get all needed labels first.
labels := make([]*Label, 0, len(opts.LableIDs))
if err = e.In("id", opts.LableIDs).Find(&labels); err != nil {
@@ -735,7 +765,7 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
func GetIssueByRef(ref string) (*Issue, error) {
n := strings.IndexByte(ref, byte('#'))
if n == -1 {
return nil, ErrMissingIssueNumber
return nil, errMissingIssueNumber
}
index, err := com.StrTo(ref[n+1:]).Int64()
@@ -756,7 +786,7 @@ func GetIssueByRef(ref string) (*Issue, error) {
return issue, issue.LoadAttributes()
}
// GetIssueByIndex returns raw issue without loading attributes by index in a repository.
// GetRawIssueByIndex returns raw issue without loading attributes by index in a repository.
func GetRawIssueByIndex(repoID, index int64) (*Issue, error) {
issue := &Issue{
RepoID: repoID,
@@ -796,6 +826,7 @@ func GetIssueByID(id int64) (*Issue, error) {
return getIssueByID(x, id)
}
// IssuesOptions represents options of an issue.
type IssuesOptions struct {
UserID int64
AssigneeID int64
@@ -820,20 +851,12 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) {
sess := x.Limit(setting.UI.IssuePagingNum, (opts.Page-1)*setting.UI.IssuePagingNum)
if opts.RepoID > 0 {
sess.
Where("issue.repo_id=?", opts.RepoID).
And("issue.is_closed=?", opts.IsClosed)
} else if opts.RepoIDs != nil {
sess.And("issue.repo_id=?", opts.RepoID)
} else if len(opts.RepoIDs) > 0 {
// In case repository IDs are provided but actually no repository has issue.
if len(opts.RepoIDs) == 0 {
return make([]*Issue, 0), nil
}
sess.
In("issue.repo_id", base.Int64sToStrings(opts.RepoIDs)).
And("issue.is_closed=?", opts.IsClosed)
} else {
sess.Where("issue.is_closed=?", opts.IsClosed)
sess.In("issue.repo_id", opts.RepoIDs)
}
sess.And("issue.is_closed=?", opts.IsClosed)
if opts.AssigneeID > 0 {
sess.And("issue.assignee_id=?", opts.AssigneeID)
@@ -975,9 +998,9 @@ func NewIssueUsers(repo *Repository, issue *Issue) (err error) {
}
// PairsContains returns true when pairs list contains given issue.
func PairsContains(ius []*IssueUser, issueId, uid int64) int {
func PairsContains(ius []*IssueUser, issueID, uid int64) int {
for i := range ius {
if ius[i].IssueID == issueId &&
if ius[i].IssueID == issueID &&
ius[i].UID == uid {
return i
}
@@ -1100,6 +1123,7 @@ func parseCountResult(results []map[string][]byte) int64 {
return 0
}
// IssueStatsOptions contains parameters accepted by GetIssueStats.
type IssueStatsOptions struct {
RepoID int64
UserID int64
@@ -1185,9 +1209,9 @@ func GetUserIssueStats(repoID, uid int64, repoIDs []int64, filterMode int, isPul
Where("issue.is_closed = ?", isClosed).
And("issue.is_pull = ?", isPull)
if repoID > 0 || len(repoIDs) == 0 {
if repoID > 0 {
sess.And("repo_id = ?", repoID)
} else {
} else if len(repoIDs) > 0 {
sess.In("repo_id", repoIDs)
}
@@ -1358,10 +1382,12 @@ type Milestone struct {
ClosedDateUnix int64
}
// BeforeInsert is invoked from XORM before inserting an object of this type.
func (m *Milestone) BeforeInsert() {
m.DeadlineUnix = m.Deadline.Unix()
}
// BeforeUpdate is invoked from XORM before updating this object.
func (m *Milestone) BeforeUpdate() {
if m.NumIssues > 0 {
m.Completeness = m.NumClosedIssues * 100 / m.NumIssues
@@ -1373,6 +1399,8 @@ func (m *Milestone) BeforeUpdate() {
m.ClosedDateUnix = m.ClosedDate.Unix()
}
// AfterSet is invoked from XORM after setting the value of a field of
// this object.
func (m *Milestone) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "num_closed_issues":
@@ -1397,11 +1425,12 @@ func (m *Milestone) AfterSet(colName string, _ xorm.Cell) {
// State returns string representation of milestone status.
func (m *Milestone) State() api.StateType {
if m.IsClosed {
return api.STATE_CLOSED
return api.StateClosed
}
return api.STATE_OPEN
return api.StateOpen
}
// APIFormat returns this Milestone in API format.
func (m *Milestone) APIFormat() *api.Milestone {
apiMilestone := &api.Milestone{
ID: m.ID,
@@ -1452,7 +1481,7 @@ func getMilestoneByRepoID(e Engine, repoID, id int64) (*Milestone, error) {
return m, nil
}
// GetWebhookByRepoID returns the milestone in a repository.
// GetMilestoneByRepoID returns the milestone in a repository.
func GetMilestoneByRepoID(repoID, id int64) (*Milestone, error) {
return getMilestoneByRepoID(x, repoID, id)
}
@@ -1684,10 +1713,13 @@ type Attachment struct {
CreatedUnix int64
}
// BeforeInsert is invoked from XORM before inserting an object of this type.
func (a *Attachment) BeforeInsert() {
a.CreatedUnix = time.Now().Unix()
}
// AfterSet is invoked from XORM after setting the value of a field of
// this object.
func (a *Attachment) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created_unix":
@@ -1695,14 +1727,15 @@ func (a *Attachment) AfterSet(colName string, _ xorm.Cell) {
}
}
// AttachmentLocalPath returns where attachment is stored in local file system based on given UUID.
// AttachmentLocalPath returns where attachment is stored in local file
// system based on given UUID.
func AttachmentLocalPath(uuid string) string {
return path.Join(setting.AttachmentPath, uuid[0:1], uuid[1:2], uuid)
}
// LocalPath returns where attachment is stored in local file system.
func (attach *Attachment) LocalPath() string {
return AttachmentLocalPath(attach.UUID)
func (a *Attachment) LocalPath() string {
return AttachmentLocalPath(a.UUID)
}
// NewAttachment creates a new attachment object.
@@ -1802,8 +1835,8 @@ 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)
func DeleteAttachmentsByIssue(issueID int64, remove bool) (int, error) {
attachments, err := GetAttachmentsByIssueID(issueID)
if err != nil {
return 0, err
@@ -1813,8 +1846,8 @@ 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)
func DeleteAttachmentsByComment(commentID int64, remove bool) (int, error) {
attachments, err := GetAttachmentsByCommentID(commentID)
if err != nil {
return 0, err

View File

@@ -21,6 +21,7 @@ import (
// CommentType defines whether a comment is just a simple comment, an action (like close) or a reference.
type CommentType int
// Enumerate all the comment types
const (
// Plain comment, can be associated with a commit (CommitID > 0) and a line (LineNum > 0)
CommentTypeComment CommentType = iota
@@ -37,8 +38,10 @@ const (
CommentTypePullRef
)
// CommentTag defines comment tag type
type CommentTag int
// Enumerate all the comment tag types
const (
CommentTagNone CommentTag = iota
CommentTagPoster
@@ -72,15 +75,19 @@ type Comment struct {
ShowTag CommentTag `xorm:"-"`
}
// BeforeInsert will be invoked by XORM before inserting a record
// representing this object.
func (c *Comment) BeforeInsert() {
c.CreatedUnix = time.Now().Unix()
c.UpdatedUnix = c.CreatedUnix
}
// BeforeUpdate is invoked from XORM before updating this object.
func (c *Comment) BeforeUpdate() {
c.UpdatedUnix = time.Now().Unix()
}
// AfterSet is invoked from XORM after setting the value of a field of this object.
func (c *Comment) AfterSet(colName string, _ xorm.Cell) {
var err error
switch colName {
@@ -107,6 +114,7 @@ func (c *Comment) AfterSet(colName string, _ xorm.Cell) {
}
}
// AfterDelete is invoked from XORM after the object is deleted.
func (c *Comment) AfterDelete() {
_, err := DeleteAttachmentsByComment(c.ID, true)
@@ -115,6 +123,7 @@ func (c *Comment) AfterDelete() {
}
}
// APIFormat converts a Comment to the api.Comment format
func (c *Comment) APIFormat() *api.Comment {
return &api.Comment{
ID: c.ID,
@@ -137,21 +146,21 @@ func (c *Comment) EventTag() string {
// MailParticipants sends new comment emails to repository watchers
// and mentioned people.
func (cmt *Comment) MailParticipants(opType ActionType, issue *Issue) (err error) {
mentions := markdown.FindAllMentions(cmt.Content)
if err = UpdateIssueMentions(cmt.IssueID, mentions); err != nil {
return fmt.Errorf("UpdateIssueMentions [%d]: %v", cmt.IssueID, err)
func (c *Comment) MailParticipants(opType ActionType, issue *Issue) (err error) {
mentions := markdown.FindAllMentions(c.Content)
if err = UpdateIssueMentions(c.IssueID, mentions); err != nil {
return fmt.Errorf("UpdateIssueMentions [%d]: %v", c.IssueID, err)
}
switch opType {
case ActionCommentIssue:
issue.Content = cmt.Content
issue.Content = c.Content
case ActionCloseIssue:
issue.Content = fmt.Sprintf("Closed #%d", issue.Index)
case ActionReopenIssue:
issue.Content = fmt.Sprintf("Reopened #%d", issue.Index)
}
if err = mailIssueCommentToParticipants(issue, cmt.Poster, mentions); err != nil {
if err = mailIssueCommentToParticipants(issue, c.Poster, mentions); err != nil {
log.Error(4, "mailIssueCommentToParticipants: %v", err)
}
@@ -272,6 +281,7 @@ func createStatusComment(e *xorm.Session, doer *User, repo *Repository, issue *I
})
}
// CreateCommentOptions defines options for creating comment
type CreateCommentOptions struct {
Type CommentType
Doer *User
@@ -374,7 +384,7 @@ func GetCommentsByIssueID(issueID int64) ([]*Comment, error) {
return getCommentsByIssueID(x, issueID)
}
// GetCommentsByIssueID returns a list of comments of an issue since a given time point.
// GetCommentsByIssueIDSince returns a list of comments of an issue since a given time point.
func GetCommentsByIssueIDSince(issueID, since int64) ([]*Comment, error) {
return getCommentsByIssueIDSince(x, issueID, since)
}

View File

@@ -14,8 +14,6 @@ import (
"github.com/go-xorm/xorm"
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/modules/base"
)
var labelColorPattern = regexp.MustCompile("#([a-fA-F0-9]{6})")
@@ -64,11 +62,12 @@ type Label struct {
IsChecked bool `xorm:"-"`
}
// APIFormat converts a Label to the api.Label format
func (label *Label) APIFormat() *api.Label {
return &api.Label{
ID: label.ID,
Name: label.Name,
Color: label.Color,
Color: strings.TrimLeft(label.Color, "#"),
}
}
@@ -79,9 +78,9 @@ func (label *Label) CalOpenIssues() {
// ForegroundColor calculates the text color for labels based
// on their background color.
func (l *Label) ForegroundColor() template.CSS {
if strings.HasPrefix(l.Color, "#") {
if color, err := strconv.ParseUint(l.Color[1:], 16, 64); err == nil {
func (label *Label) ForegroundColor() template.CSS {
if strings.HasPrefix(label.Color, "#") {
if color, err := strconv.ParseUint(label.Color[1:], 16, 64); err == nil {
r := float32(0xFF & (color >> 16))
g := float32(0xFF & (color >> 8))
b := float32(0xFF & color)
@@ -103,6 +102,27 @@ func NewLabels(labels ...*Label) error {
return err
}
// getLabelInRepoByName returns a label by Name in given repository.
// If pass repoID as 0, then ORM will ignore limitation of repository
// and can return arbitrary label with any valid ID.
func getLabelInRepoByName(e Engine, repoID int64, labelName string) (*Label, error) {
if len(labelName) <= 0 {
return nil, ErrLabelNotExist{0, repoID}
}
l := &Label{
Name: labelName,
RepoID: repoID,
}
has, err := x.Get(l)
if err != nil {
return nil, err
} else if !has {
return nil, ErrLabelNotExist{0, l.RepoID}
}
return l, nil
}
// getLabelInRepoByID returns a label by ID in given repository.
// If pass repoID as 0, then ORM will ignore limitation of repository
// and can return arbitrary label with any valid ID.
@@ -129,6 +149,11 @@ func GetLabelByID(id int64) (*Label, error) {
return getLabelInRepoByID(x, 0, id)
}
// GetLabelInRepoByName returns a label by name in given repository.
func GetLabelInRepoByName(repoID int64, labelName string) (*Label, error) {
return getLabelInRepoByName(x, repoID, labelName)
}
// GetLabelInRepoByID returns a label by ID in given repository.
func GetLabelInRepoByID(repoID, labelID int64) (*Label, error) {
return getLabelInRepoByID(x, repoID, labelID)
@@ -140,7 +165,7 @@ func GetLabelsInRepoByIDs(repoID int64, labelIDs []int64) ([]*Label, error) {
labels := make([]*Label, 0, len(labelIDs))
return labels, x.
Where("repo_id = ?", repoID).
In("id", base.Int64sToStrings(labelIDs)).
In("id", labelIDs).
Asc("name").
Find(&labels)
}
@@ -170,7 +195,7 @@ func getLabelsByIssueID(e Engine, issueID int64) ([]*Label, error) {
labels := make([]*Label, 0, len(labelIDs))
return labels, e.
Where("id > 0").
In("id", base.Int64sToStrings(labelIDs)).
In("id", labelIDs).
Asc("name").
Find(&labels)
}

View File

@@ -14,7 +14,7 @@ import (
"code.gitea.io/gitea/modules/setting"
)
func (issue *Issue) MailSubject() string {
func (issue *Issue) mailSubject() string {
return fmt.Sprintf("[%s] %s (#%d)", issue.Repo.Name, issue.Title, issue.Index)
}

View File

@@ -24,6 +24,7 @@ import (
"code.gitea.io/gitea/modules/log"
)
// LoginType represents an login type.
type LoginType int
// Note: new type must append to the end of list to maintain compatibility.
@@ -36,6 +37,7 @@ const (
LoginDLDAP // 5
)
// LoginNames contains the name of LoginType values.
var LoginNames = map[LoginType]string{
LoginLDAP: "LDAP (via BindDN)",
LoginDLDAP: "LDAP (simple auth)", // Via direct bind
@@ -43,6 +45,7 @@ var LoginNames = map[LoginType]string{
LoginPAM: "PAM",
}
// SecurityProtocolNames contains the name of SecurityProtocol values.
var SecurityProtocolNames = map[ldap.SecurityProtocol]string{
ldap.SecurityProtocolUnencrypted: "Unencrypted",
ldap.SecurityProtocolLDAPS: "LDAPS",
@@ -56,22 +59,28 @@ var (
_ core.Conversion = &PAMConfig{}
)
// LDAPConfig holds configuration for LDAP login source.
type LDAPConfig struct {
*ldap.Source
}
// FromDB fills up a LDAPConfig from serialized format.
func (cfg *LDAPConfig) FromDB(bs []byte) error {
return json.Unmarshal(bs, &cfg)
}
// ToDB exports a LDAPConfig to a serialized format.
func (cfg *LDAPConfig) ToDB() ([]byte, error) {
return json.Marshal(cfg)
}
// SecurityProtocolName returns the name of configured security
// protocol.
func (cfg *LDAPConfig) SecurityProtocolName() string {
return SecurityProtocolNames[cfg.SecurityProtocol]
}
// SMTPConfig holds configuration for the SMTP login source.
type SMTPConfig struct {
Auth string
Host string
@@ -81,22 +90,27 @@ type SMTPConfig struct {
SkipVerify bool
}
// FromDB fills up an SMTPConfig from serialized format.
func (cfg *SMTPConfig) FromDB(bs []byte) error {
return json.Unmarshal(bs, cfg)
}
// ToDB exports an SMTPConfig to a serialized format.
func (cfg *SMTPConfig) ToDB() ([]byte, error) {
return json.Marshal(cfg)
}
// PAMConfig holds configuration for the PAM login source.
type PAMConfig struct {
ServiceName string // pam service (e.g. system-auth)
}
// FromDB fills up a PAMConfig from serialized format.
func (cfg *PAMConfig) FromDB(bs []byte) error {
return json.Unmarshal(bs, &cfg)
}
// ToDB exports a PAMConfig to a serialized format.
func (cfg *PAMConfig) ToDB() ([]byte, error) {
return json.Marshal(cfg)
}
@@ -115,13 +129,15 @@ type LoginSource struct {
UpdatedUnix int64
}
func (s *LoginSource) BeforeInsert() {
s.CreatedUnix = time.Now().Unix()
s.UpdatedUnix = s.CreatedUnix
// BeforeInsert is invoked from XORM before inserting an object of this type.
func (source *LoginSource) BeforeInsert() {
source.CreatedUnix = time.Now().Unix()
source.UpdatedUnix = source.CreatedUnix
}
func (s *LoginSource) BeforeUpdate() {
s.UpdatedUnix = time.Now().Unix()
// BeforeUpdate is invoked from XORM before updating this object.
func (source *LoginSource) BeforeUpdate() {
source.UpdatedUnix = time.Now().Unix()
}
// Cell2Int64 converts a xorm.Cell type to int64,
@@ -135,6 +151,7 @@ func Cell2Int64(val xorm.Cell) int64 {
return (*val).(int64)
}
// BeforeSet is invoked from XORM before setting the value of a field of this object.
func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
switch colName {
case "type":
@@ -151,41 +168,49 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
}
}
func (s *LoginSource) AfterSet(colName string, _ xorm.Cell) {
// AfterSet is invoked from XORM after setting the value of a field of this object.
func (source *LoginSource) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created_unix":
s.Created = time.Unix(s.CreatedUnix, 0).Local()
source.Created = time.Unix(source.CreatedUnix, 0).Local()
case "updated_unix":
s.Updated = time.Unix(s.UpdatedUnix, 0).Local()
source.Updated = time.Unix(source.UpdatedUnix, 0).Local()
}
}
// TypeName return name of this login source type.
func (source *LoginSource) TypeName() string {
return LoginNames[source.Type]
}
// IsLDAP returns true of this source is of the LDAP type.
func (source *LoginSource) IsLDAP() bool {
return source.Type == LoginLDAP
}
// IsDLDAP returns true of this source is of the DLDAP type.
func (source *LoginSource) IsDLDAP() bool {
return source.Type == LoginDLDAP
}
// IsSMTP returns true of this source is of the SMTP type.
func (source *LoginSource) IsSMTP() bool {
return source.Type == LoginSMTP
}
// IsPAM returns true of this source is of the PAM type.
func (source *LoginSource) IsPAM() bool {
return source.Type == LoginPAM
}
// HasTLS returns true of this source supports TLS.
func (source *LoginSource) HasTLS() bool {
return ((source.IsLDAP() || source.IsDLDAP()) &&
source.LDAP().SecurityProtocol > ldap.SecurityProtocolUnencrypted) ||
source.IsSMTP()
}
// UseTLS returns true of this source is configured to use TLS.
func (source *LoginSource) UseTLS() bool {
switch source.Type {
case LoginLDAP, LoginDLDAP:
@@ -197,6 +222,8 @@ func (source *LoginSource) UseTLS() bool {
return false
}
// SkipVerify returns true if this source is configured to skip SSL
// verification.
func (source *LoginSource) SkipVerify() bool {
switch source.Type {
case LoginLDAP, LoginDLDAP:
@@ -208,17 +235,23 @@ func (source *LoginSource) SkipVerify() bool {
return false
}
// LDAP returns LDAPConfig for this source, if of LDAP type.
func (source *LoginSource) LDAP() *LDAPConfig {
return source.Cfg.(*LDAPConfig)
}
// SMTP returns SMTPConfig for this source, if of SMTP type.
func (source *LoginSource) SMTP() *SMTPConfig {
return source.Cfg.(*SMTPConfig)
}
// PAM returns PAMConfig for this source, if of PAM type.
func (source *LoginSource) PAM() *PAMConfig {
return source.Cfg.(*PAMConfig)
}
// CreateLoginSource inserts a LoginSource in the DB if not already
// existing with the given name.
func CreateLoginSource(source *LoginSource) error {
has, err := x.Get(&LoginSource{Name: source.Name})
if err != nil {
@@ -231,6 +264,7 @@ func CreateLoginSource(source *LoginSource) error {
return err
}
// LoginSources returns a slice of all login sources found in DB.
func LoginSources() ([]*LoginSource, error) {
auths := make([]*LoginSource, 0, 5)
return auths, x.Find(&auths)
@@ -248,11 +282,13 @@ func GetLoginSourceByID(id int64) (*LoginSource, error) {
return source, nil
}
// UpdateSource updates a LoginSource record in DB.
func UpdateSource(source *LoginSource) error {
_, err := x.Id(source.ID).AllCols().Update(source)
return err
}
// DeleteSource deletes a LoginSource record in DB.
func DeleteSource(source *LoginSource) error {
count, err := x.Count(&User{LoginSource: source.ID})
if err != nil {
@@ -292,11 +328,11 @@ func composeFullName(firstname, surname, username string) string {
// LoginViaLDAP queries if login/password is valid against the LDAP directory pool,
// and create a local user if success when enabled.
func LoginViaLDAP(user *User, login, passowrd string, source *LoginSource, autoRegister bool) (*User, error) {
username, fn, sn, mail, isAdmin, succeed := source.Cfg.(*LDAPConfig).SearchEntry(login, passowrd, source.Type == LoginDLDAP)
func LoginViaLDAP(user *User, login, password string, source *LoginSource, autoRegister bool) (*User, error) {
username, fn, sn, mail, isAdmin, succeed := source.Cfg.(*LDAPConfig).SearchEntry(login, password, source.Type == LoginDLDAP)
if !succeed {
// User not in LDAP, do nothing
return nil, ErrUserNotExist{0, login}
return nil, ErrUserNotExist{0, login, 0}
}
if !autoRegister {
@@ -357,13 +393,16 @@ func (auth *smtpLoginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
return nil, nil
}
// SMTP authentication type names.
const (
SMTPPlain = "PLAIN"
SMTPLogin = "LOGIN"
)
// SMTPAuths contains available SMTP authentication type names.
var SMTPAuths = []string{SMTPPlain, SMTPLogin}
// SMTPAuth performs an SMTP authentication.
func SMTPAuth(a smtp.Auth, cfg *SMTPConfig) error {
c, err := smtp.Dial(fmt.Sprintf("%s:%d", cfg.Host, cfg.Port))
if err != nil {
@@ -404,9 +443,9 @@ func LoginViaSMTP(user *User, login, password string, sourceID int64, cfg *SMTPC
if len(cfg.AllowedDomains) > 0 {
idx := strings.Index(login, "@")
if idx == -1 {
return nil, ErrUserNotExist{0, login}
return nil, ErrUserNotExist{0, login, 0}
} else if !com.IsSliceContainsStr(strings.Split(cfg.AllowedDomains, ","), login[idx+1:]) {
return nil, ErrUserNotExist{0, login}
return nil, ErrUserNotExist{0, login, 0}
}
}
@@ -425,7 +464,7 @@ func LoginViaSMTP(user *User, login, password string, sourceID int64, cfg *SMTPC
tperr, ok := err.(*textproto.Error)
if (ok && tperr.Code == 535) ||
strings.Contains(err.Error(), "Username and Password not accepted") {
return nil, ErrUserNotExist{0, login}
return nil, ErrUserNotExist{0, login, 0}
}
return nil, err
}
@@ -463,9 +502,9 @@ func LoginViaSMTP(user *User, login, password string, sourceID int64, cfg *SMTPC
// LoginViaPAM queries if login/password is valid against the PAM,
// and create a local user if success when enabled.
func LoginViaPAM(user *User, login, password string, sourceID int64, cfg *PAMConfig, autoRegister bool) (*User, error) {
if err := pam.PAMAuth(cfg.ServiceName, login, password); err != nil {
if err := pam.Auth(cfg.ServiceName, login, password); err != nil {
if strings.Contains(err.Error(), "Authentication failure") {
return nil, ErrUserNotExist{0, login}
return nil, ErrUserNotExist{0, login, 0}
}
return nil, err
}
@@ -487,6 +526,7 @@ func LoginViaPAM(user *User, login, password string, sourceID int64, cfg *PAMCon
return user, CreateUser(user)
}
// ExternalUserLogin attempts a login using external source types.
func ExternalUserLogin(user *User, login, password string, source *LoginSource, autoRegister bool) (*User, error) {
if !source.IsActived {
return nil, ErrLoginSourceNotActived
@@ -505,7 +545,7 @@ func ExternalUserLogin(user *User, login, password string, source *LoginSource,
}
// UserSignIn validates user name and password.
func UserSignIn(username, passowrd string) (*User, error) {
func UserSignIn(username, password string) (*User, error) {
var user *User
if strings.Contains(username, "@") {
user = &User{Email: strings.ToLower(username)}
@@ -521,11 +561,11 @@ func UserSignIn(username, passowrd string) (*User, error) {
if hasUser {
switch user.LoginType {
case LoginNoType, LoginPlain:
if user.ValidatePassword(passowrd) {
if user.ValidatePassword(password) {
return user, nil
}
return nil, ErrUserNotExist{user.ID, user.Name}
return nil, ErrUserNotExist{user.ID, user.Name, 0}
default:
var source LoginSource
@@ -536,7 +576,7 @@ func UserSignIn(username, passowrd string) (*User, error) {
return nil, ErrLoginSourceNotExist{user.LoginSource}
}
return ExternalUserLogin(user, user.LoginName, passowrd, &source, false)
return ExternalUserLogin(user, user.LoginName, password, &source, false)
}
}
@@ -546,7 +586,7 @@ func UserSignIn(username, passowrd string) (*User, error) {
}
for _, source := range sources {
authUser, err := ExternalUserLogin(nil, username, passowrd, source, true)
authUser, err := ExternalUserLogin(nil, username, password, source, true)
if err == nil {
return authUser, nil
}
@@ -554,5 +594,5 @@ func UserSignIn(username, passowrd string) (*User, error) {
log.Warn("Failed to login '%s' via '%s': %v", username, source.Name, err)
}
return nil, ErrUserNotExist{user.ID, user.Name}
return nil, ErrUserNotExist{user.ID, user.Name, 0}
}

View File

@@ -5,58 +5,45 @@
package models
import (
"bytes"
"fmt"
"html/template"
"path"
"gopkg.in/gomail.v2"
"gopkg.in/macaron.v1"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/mailer"
"code.gitea.io/gitea/modules/markdown"
"code.gitea.io/gitea/modules/setting"
"gopkg.in/gomail.v2"
"gopkg.in/macaron.v1"
)
const (
MailAuthActivate base.TplName = "auth/activate"
MailAuthActivateEmail base.TplName = "auth/activate_email"
MailAuthResetPassword base.TplName = "auth/reset_passwd"
MailAuthRegisterNotify base.TplName = "auth/register_notify"
mailAuthActivate base.TplName = "auth/activate"
mailAuthActivateEmail base.TplName = "auth/activate_email"
mailAuthResetPassword base.TplName = "auth/reset_passwd"
mailAuthRegisterNotify base.TplName = "auth/register_notify"
MailIssueComment base.TplName = "issue/comment"
MailIssueMention base.TplName = "issue/mention"
mailIssueComment base.TplName = "issue/comment"
mailIssueMention base.TplName = "issue/mention"
MailNotifyCollaborator base.TplName = "notify/collaborator"
mailNotifyCollaborator base.TplName = "notify/collaborator"
)
type MailRender interface {
HTMLString(string, interface{}, ...macaron.HTMLOptions) (string, error)
}
var mailRender MailRender
func InitMailRender(dir, appendDir string, funcMap []template.FuncMap) {
opt := &macaron.RenderOptions{
Directory: dir,
AppendDirectories: []string{appendDir},
Funcs: funcMap,
Extensions: []string{".tmpl", ".html"},
}
ts := macaron.NewTemplateSet()
ts.Set(macaron.DEFAULT_TPL_SET_NAME, opt)
mailRender = &macaron.TplRender{
TemplateSet: ts,
Opt: opt,
}
var templates *template.Template
// InitMailRender initializes the macaron mail renderer
func InitMailRender(tmpls *template.Template) {
templates = tmpls
}
// SendTestMail sends a test mail
func SendTestMail(email string) error {
return gomail.Send(&mailer.Sender{}, mailer.NewMessage([]string{email}, "Gogs Test Email!", "Gogs Test Email!").Message)
}
// SendUserMail sends a mail to the user
func SendUserMail(c *macaron.Context, u *User, tpl base.TplName, code, subject, info string) {
data := map[string]interface{}{
"Username": u.DisplayName(),
@@ -64,27 +51,31 @@ func SendUserMail(c *macaron.Context, u *User, tpl base.TplName, code, subject,
"ResetPwdCodeLives": setting.Service.ResetPwdCodeLives / 60,
"Code": code,
}
body, err := mailRender.HTMLString(string(tpl), data)
if err != nil {
log.Error(3, "HTMLString: %v", err)
var content bytes.Buffer
if err := templates.ExecuteTemplate(&content, string(tpl), data); err != nil {
log.Error(3, "Template: %v", err)
return
}
msg := mailer.NewMessage([]string{u.Email}, subject, body)
msg := mailer.NewMessage([]string{u.Email}, subject, content.String())
msg.Info = fmt.Sprintf("UID: %d, %s", u.ID, info)
mailer.SendAsync(msg)
}
// SendActivateAccountMail sends an activation mail to the user
func SendActivateAccountMail(c *macaron.Context, u *User) {
SendUserMail(c, u, MailAuthActivate, u.GenerateActivateCode(), c.Tr("mail.activate_account"), "activate account")
SendUserMail(c, u, mailAuthActivate, u.GenerateActivateCode(), c.Tr("mail.activate_account"), "activate account")
}
// SendResetPasswordMail sends a password reset mail to the user
func SendResetPasswordMail(c *macaron.Context, u *User) {
SendUserMail(c, u, MailAuthResetPassword, u.GenerateActivateCode(), c.Tr("mail.reset_password"), "reset password")
SendUserMail(c, u, mailAuthResetPassword, u.GenerateActivateCode(), c.Tr("mail.reset_password"), "reset password")
}
// SendActivateAccountMail sends confirmation email.
// SendActivateEmailMail sends confirmation email.
func SendActivateEmailMail(c *macaron.Context, u *User, email *EmailAddress) {
data := map[string]interface{}{
"Username": u.DisplayName(),
@@ -92,13 +83,15 @@ func SendActivateEmailMail(c *macaron.Context, u *User, email *EmailAddress) {
"Code": u.GenerateEmailActivateCode(email.Email),
"Email": email.Email,
}
body, err := mailRender.HTMLString(string(MailAuthActivateEmail), data)
if err != nil {
log.Error(3, "HTMLString: %v", err)
var content bytes.Buffer
if err := templates.ExecuteTemplate(&content, string(mailAuthActivateEmail), data); err != nil {
log.Error(3, "Template: %v", err)
return
}
msg := mailer.NewMessage([]string{email.Email}, c.Tr("mail.activate_email"), body)
msg := mailer.NewMessage([]string{email.Email}, c.Tr("mail.activate_email"), content.String())
msg.Info = fmt.Sprintf("UID: %d, activate email", u.ID)
mailer.SendAsync(msg)
@@ -109,13 +102,15 @@ func SendRegisterNotifyMail(c *macaron.Context, u *User) {
data := map[string]interface{}{
"Username": u.DisplayName(),
}
body, err := mailRender.HTMLString(string(MailAuthRegisterNotify), data)
if err != nil {
log.Error(3, "HTMLString: %v", err)
var content bytes.Buffer
if err := templates.ExecuteTemplate(&content, string(mailAuthRegisterNotify), data); err != nil {
log.Error(3, "Template: %v", err)
return
}
msg := mailer.NewMessage([]string{u.Email}, c.Tr("mail.register_notify"), body)
msg := mailer.NewMessage([]string{u.Email}, c.Tr("mail.register_notify"), content.String())
msg.Info = fmt.Sprintf("UID: %d, registration notify", u.ID)
mailer.SendAsync(msg)
@@ -131,13 +126,15 @@ func SendCollaboratorMail(u, doer *User, repo *Repository) {
"RepoName": repoName,
"Link": repo.HTMLURL(),
}
body, err := mailRender.HTMLString(string(MailNotifyCollaborator), data)
if err != nil {
log.Error(3, "HTMLString: %v", err)
var content bytes.Buffer
if err := templates.ExecuteTemplate(&content, string(mailNotifyCollaborator), data); err != nil {
log.Error(3, "Template: %v", err)
return
}
msg := mailer.NewMessage([]string{u.Email}, subject, body)
msg := mailer.NewMessage([]string{u.Email}, subject, content.String())
msg.Info = fmt.Sprintf("UID: %d, add collaborator", u.ID)
mailer.SendAsync(msg)
@@ -152,15 +149,18 @@ func composeTplData(subject, body, link string) map[string]interface{} {
}
func composeIssueMessage(issue *Issue, doer *User, tplName base.TplName, tos []string, info string) *mailer.Message {
subject := issue.MailSubject()
subject := issue.mailSubject()
body := string(markdown.RenderSpecialLink([]byte(issue.Content), issue.Repo.HTMLURL(), issue.Repo.ComposeMetas()))
data := composeTplData(subject, body, issue.HTMLURL())
data["Doer"] = doer
content, err := mailRender.HTMLString(string(tplName), data)
if err != nil {
log.Error(3, "HTMLString (%s): %v", tplName, err)
var content bytes.Buffer
if err := templates.ExecuteTemplate(&content, string(tplName), data); err != nil {
log.Error(3, "Template: %v", err)
}
msg := mailer.NewMessageFrom(tos, fmt.Sprintf(`"%s" <%s>`, doer.DisplayName(), setting.MailService.FromEmail), subject, content)
msg := mailer.NewMessageFrom(tos, fmt.Sprintf(`"%s" <%s>`, doer.DisplayName(), setting.MailService.FromEmail), subject, content.String())
msg.Info = fmt.Sprintf("Subject: %s, %s", subject, info)
return msg
}
@@ -171,7 +171,7 @@ func SendIssueCommentMail(issue *Issue, doer *User, tos []string) {
return
}
mailer.SendAsync(composeIssueMessage(issue, doer, MailIssueComment, tos, "issue comment"))
mailer.SendAsync(composeIssueMessage(issue, doer, mailIssueComment, tos, "issue comment"))
}
// SendIssueMentionMail composes and sends issue mention emails to target receivers.
@@ -179,5 +179,5 @@ func SendIssueMentionMail(issue *Issue, doer *User, tos []string) {
if len(tos) == 0 {
return
}
mailer.SendAsync(composeIssueMessage(issue, doer, MailIssueMention, tos, "issue mention"))
mailer.SendAsync(composeIssueMessage(issue, doer, mailIssueMention, tos, "issue mention"))
}

View File

@@ -25,8 +25,9 @@ import (
"code.gitea.io/gitea/modules/setting"
)
const _MIN_DB_VER = 4
const minDBVersion = 4
// Migration describes on migration from lower version to high version
type Migration interface {
Description() string
Migrate(*xorm.Engine) error
@@ -37,19 +38,22 @@ type migration struct {
migrate func(*xorm.Engine) error
}
// NewMigration creates a new migration
func NewMigration(desc string, fn func(*xorm.Engine) error) Migration {
return &migration{desc, fn}
}
// Description returns the migration's description
func (m *migration) Description() string {
return m.description
}
// Migrate executes the migration
func (m *migration) Migrate(x *xorm.Engine) error {
return m.migrate(x)
}
// The version table. Should have only one row with id==1
// Version describes the version table. Should have only one row with id==1
type Version struct {
ID int64 `xorm:"pk autoincr"`
Version int64
@@ -57,11 +61,11 @@ type Version struct {
// This is a sequence of migrations. Add new migrations to the bottom of the list.
// If you want to "retire" a migration, remove it from the top of the list and
// update _MIN_VER_DB accordingly
// update minDBVersion accordingly
var migrations = []Migration{
// v0 -> v4: before 0.6.0 -> 0.7.33
NewMigration("fix locale file load panic", fixLocaleFileLoadPanic), // V4 -> V5:v0.6.0
NewMigration("trim action compare URL prefix", trimCommitActionAppUrlPrefix), // V5 -> V6:v0.6.3
NewMigration("trim action compare URL prefix", trimCommitActionAppURLPrefix), // V5 -> V6:v0.6.3
NewMigration("generate issue-label from issue", issueToIssueLabel), // V6 -> V7:v0.6.4
NewMigration("refactor attachment table", attachmentRefactor), // V7 -> V8:v0.6.4
NewMigration("rename pull request fields", renamePullRequestFields), // V8 -> V9:v0.6.16
@@ -72,6 +76,8 @@ var migrations = []Migration{
// v13 -> v14:v0.9.87
NewMigration("set comment updated with created", setCommentUpdatedWithCreated),
NewMigration("create user column diff view style", createUserColumnDiffViewStyle),
}
// Migrate database to current version
@@ -87,7 +93,7 @@ func Migrate(x *xorm.Engine) error {
} else if !has {
// If the version record does not exist we think
// it is a fresh installation and we can skip all migrations.
currentVersion.Version = int64(_MIN_DB_VER + len(migrations))
currentVersion.Version = int64(minDBVersion + len(migrations))
if _, err = x.InsertOne(currentVersion); err != nil {
return fmt.Errorf("insert: %v", err)
@@ -95,19 +101,19 @@ func Migrate(x *xorm.Engine) error {
}
v := currentVersion.Version
if _MIN_DB_VER > v {
log.Fatal(4, `Gogs no longer supports auto-migration from your previously installed version.
if minDBVersion > v {
log.Fatal(4, `Gogs no longer supports auto-migration from your previously installed version.
Please try to upgrade to a lower version (>= v0.6.0) first, then upgrade to current version.`)
return nil
}
if int(v-_MIN_DB_VER) > len(migrations) {
if int(v-minDBVersion) > len(migrations) {
// User downgraded Gogs.
currentVersion.Version = int64(len(migrations) + _MIN_DB_VER)
currentVersion.Version = int64(len(migrations) + minDBVersion)
_, err = x.Id(1).Update(currentVersion)
return err
}
for i, m := range migrations[v-_MIN_DB_VER:] {
for i, m := range migrations[v-minDBVersion:] {
log.Info("Migration: %s", m.Description())
if err = m.Migrate(x); err != nil {
return fmt.Errorf("do migrate: %v", err)
@@ -142,7 +148,7 @@ func fixLocaleFileLoadPanic(_ *xorm.Engine) error {
return nil
}
func trimCommitActionAppUrlPrefix(x *xorm.Engine) error {
func trimCommitActionAppURLPrefix(x *xorm.Engine) error {
type PushCommit struct {
Sha1 string
Message string
@@ -153,7 +159,7 @@ func trimCommitActionAppUrlPrefix(x *xorm.Engine) error {
type PushCommits struct {
Len int
Commits []*PushCommit
CompareUrl string
CompareURL string `json:"CompareUrl"`
}
type Action struct {
@@ -184,11 +190,11 @@ func trimCommitActionAppUrlPrefix(x *xorm.Engine) error {
return fmt.Errorf("unmarshal action content[%d]: %v", actID, err)
}
infos := strings.Split(pushCommits.CompareUrl, "/")
infos := strings.Split(pushCommits.CompareURL, "/")
if len(infos) <= 4 {
continue
}
pushCommits.CompareUrl = strings.Join(infos[len(infos)-4:], "/")
pushCommits.CompareURL = strings.Join(infos[len(infos)-4:], "/")
p, err := json.Marshal(pushCommits)
if err != nil {
@@ -461,27 +467,34 @@ func generateOrgRandsAndSalt(x *xorm.Engine) (err error) {
return sess.Commit()
}
// TAction defines the struct for migrating table action
type TAction struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TAction) TableName() string { return "action" }
// TNotice defines the struct for migrating table notice
type TNotice struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TNotice) TableName() string { return "notice" }
// TComment defines the struct for migrating table comment
type TComment struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TComment) TableName() string { return "comment" }
// TIssue defines the struct for migrating table issue
type TIssue struct {
ID int64 `xorm:"pk autoincr"`
DeadlineUnix int64
@@ -489,99 +502,124 @@ type TIssue struct {
UpdatedUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TIssue) TableName() string { return "issue" }
// TMilestone defines the struct for migrating table milestone
type TMilestone struct {
ID int64 `xorm:"pk autoincr"`
DeadlineUnix int64
ClosedDateUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TMilestone) TableName() string { return "milestone" }
// TAttachment defines the struct for migrating table attachment
type TAttachment struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TAttachment) TableName() string { return "attachment" }
// TLoginSource defines the struct for migrating table login_source
type TLoginSource struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
UpdatedUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TLoginSource) TableName() string { return "login_source" }
// TPull defines the struct for migrating table pull_request
type TPull struct {
ID int64 `xorm:"pk autoincr"`
MergedUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TPull) TableName() string { return "pull_request" }
// TRelease defines the struct for migrating table release
type TRelease struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TRelease) TableName() string { return "release" }
// TRepo defines the struct for migrating table repository
type TRepo struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
UpdatedUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TRepo) TableName() string { return "repository" }
// TMirror defines the struct for migrating table mirror
type TMirror struct {
ID int64 `xorm:"pk autoincr"`
UpdatedUnix int64
NextUpdateUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TMirror) TableName() string { return "mirror" }
// TPublicKey defines the struct for migrating table public_key
type TPublicKey struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
UpdatedUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TPublicKey) TableName() string { return "public_key" }
// TDeployKey defines the struct for migrating table deploy_key
type TDeployKey struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
UpdatedUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TDeployKey) TableName() string { return "deploy_key" }
// TAccessToken defines the struct for migrating table access_token
type TAccessToken struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
UpdatedUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TAccessToken) TableName() string { return "access_token" }
// TUser defines the struct for migrating table user
type TUser struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
UpdatedUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TUser) TableName() string { return "user" }
// TWebhook defines the struct for migrating table webhook
type TWebhook struct {
ID int64 `xorm:"pk autoincr"`
CreatedUnix int64
UpdatedUnix int64
}
// TableName will be invoked by XORM to customrize the table name
func (t *TWebhook) TableName() string { return "webhook" }
func convertDateToUnix(x *xorm.Engine) (err error) {

View File

@@ -22,3 +22,17 @@ func setCommentUpdatedWithCreated(x *xorm.Engine) (err error) {
}
return nil
}
// UserV14 describes the added fields for migrating from v13 -> v14
type UserV14 struct {
DiffViewStyle string `xorm:"NOT NULL DEFAULT ''"`
}
// TableName will be invoked by XORM to customrize the table name
func (*UserV14) TableName() string {
return "user"
}
func createUserColumnDiffViewStyle(x *xorm.Engine) error {
return x.Sync2(new(UserV14))
}

View File

@@ -13,9 +13,12 @@ import (
"path"
"strings"
// Needed for the MySQL driver
_ "github.com/go-sql-driver/mysql"
"github.com/go-xorm/core"
"github.com/go-xorm/xorm"
// Needed for the Postgresql driver
_ "github.com/lib/pq"
"code.gitea.io/gitea/models/migrations"
@@ -45,36 +48,68 @@ func sessionRelease(sess *xorm.Session) {
}
var (
x *xorm.Engine
tables []interface{}
x *xorm.Engine
tables []interface{}
// HasEngine specifies if we have a xorm.Engine
HasEngine bool
// DbCfg holds the database settings
DbCfg struct {
Type, Host, Name, User, Passwd, Path, SSLMode string
}
// EnableSQLite3 use SQLite3
EnableSQLite3 bool
EnableTiDB bool
// EnableTiDB enable TiDB
EnableTiDB bool
)
func init() {
tables = append(tables,
new(User), new(PublicKey), new(AccessToken),
new(Repository), new(DeployKey), new(Collaboration), new(Access), new(Upload),
new(Watch), new(Star), new(Follow), new(Action),
new(Issue), new(PullRequest), new(Comment), new(Attachment), new(IssueUser),
new(Label), new(IssueLabel), new(Milestone),
new(Mirror), new(Release), new(LoginSource), new(Webhook),
new(UpdateTask), new(HookTask),
new(Team), new(OrgUser), new(TeamUser), new(TeamRepo),
new(Notice), new(EmailAddress))
new(User),
new(PublicKey),
new(AccessToken),
new(Repository),
new(DeployKey),
new(Collaboration),
new(Access),
new(Upload),
new(Watch),
new(Star),
new(Follow),
new(Action),
new(Issue),
new(PullRequest),
new(Comment),
new(Attachment),
new(IssueUser),
new(Label),
new(IssueLabel),
new(Milestone),
new(Mirror),
new(Release),
new(LoginSource),
new(Webhook),
new(UpdateTask),
new(HookTask),
new(Team),
new(OrgUser),
new(TeamUser),
new(TeamRepo),
new(Notice),
new(EmailAddress),
new(Notification),
)
gonicNames := []string{"SSL"}
gonicNames := []string{"SSL", "UID"}
for _, name := range gonicNames {
core.LintGonicMapper[name] = true
}
}
// LoadConfigs loads the database settings
func LoadConfigs() {
sec := setting.Cfg.Section("database")
DbCfg.Type = sec.Key("DB_TYPE").String()
@@ -115,7 +150,7 @@ func parsePostgreSQLHostPort(info string) (string, string) {
func getEngine() (*xorm.Engine, error) {
connStr := ""
var Param string = "?"
var Param = "?"
if strings.Contains(DbCfg.Name, Param) {
Param = "&"
}
@@ -139,7 +174,7 @@ func getEngine() (*xorm.Engine, error) {
}
case "sqlite3":
if !EnableSQLite3 {
return nil, errors.New("This binary version does not build support for SQLite3.")
return nil, errors.New("this binary version does not build support for SQLite3")
}
if err := os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm); err != nil {
return nil, fmt.Errorf("Fail to create directories: %v", err)
@@ -147,7 +182,7 @@ func getEngine() (*xorm.Engine, error) {
connStr = "file:" + DbCfg.Path + "?cache=shared&mode=rwc"
case "tidb":
if !EnableTiDB {
return nil, errors.New("This binary version does not build support for TiDB.")
return nil, errors.New("this binary version does not build support for TiDB")
}
if err := os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm); err != nil {
return nil, fmt.Errorf("Fail to create directories: %v", err)
@@ -159,6 +194,7 @@ func getEngine() (*xorm.Engine, error) {
return xorm.NewEngine(DbCfg.Type, connStr)
}
// NewTestEngine sets a new test xorm.Engine
func NewTestEngine(x *xorm.Engine) (err error) {
x, err = getEngine()
if err != nil {
@@ -169,6 +205,7 @@ func NewTestEngine(x *xorm.Engine) (err error) {
return x.StoreEngine("InnoDB").Sync2(tables...)
}
// SetEngine sets the xorm.Engine
func SetEngine() (err error) {
x, err = getEngine()
if err != nil {
@@ -180,7 +217,10 @@ func SetEngine() (err error) {
// WARNING: for serv command, MUST remove the output to os.stdout,
// so use log file to instead print to stdout.
logPath := path.Join(setting.LogRootPath, "xorm.log")
os.MkdirAll(path.Dir(logPath), os.ModePerm)
if err := os.MkdirAll(path.Dir(logPath), os.ModePerm); err != nil {
return fmt.Errorf("Fail to create dir %s: %v", logPath, err)
}
f, err := os.Create(logPath)
if err != nil {
@@ -191,22 +231,28 @@ func SetEngine() (err error) {
return nil
}
// NewEngine initializes a new xorm.Engine
func NewEngine() (err error) {
if err = SetEngine(); err != nil {
return err
}
if err = x.Ping(); err != nil {
return err
}
if err = migrations.Migrate(x); err != nil {
return fmt.Errorf("migrate: %v", err)
}
if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil {
return fmt.Errorf("sync database struct error: %v\n", err)
return fmt.Errorf("sync database struct error: %v", err)
}
return nil
}
// Statistic contains the database statistics
type Statistic struct {
Counter struct {
User, Org, PublicKey,
@@ -218,6 +264,7 @@ type Statistic struct {
}
}
// GetStatistic returns the database statistics
func GetStatistic() (stats Statistic) {
stats.Counter.User = CountUsers()
stats.Counter.Org = CountOrganizations()
@@ -244,6 +291,7 @@ func GetStatistic() (stats Statistic) {
return
}
// Ping tests if database is alive
func Ping() error {
return x.Ping()
}

184
models/notification.go Normal file
View File

@@ -0,0 +1,184 @@
package models
import (
"time"
)
type (
// NotificationStatus is the status of the notification (read or unread)
NotificationStatus uint8
// NotificationSource is the source of the notification (issue, PR, commit, etc)
NotificationSource uint8
)
const (
// NotificationStatusUnread represents an unread notification
NotificationStatusUnread NotificationStatus = iota + 1
// NotificationStatusRead represents a read notification
NotificationStatusRead
)
const (
// NotificationSourceIssue is a notification of an issue
NotificationSourceIssue NotificationSource = iota + 1
// NotificationSourcePullRequest is a notification of a pull request
NotificationSourcePullRequest
// NotificationSourceCommit is a notification of a commit
NotificationSourceCommit
)
// Notification represents a notification
type Notification struct {
ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"INDEX NOT NULL"`
RepoID int64 `xorm:"INDEX NOT NULL"`
Status NotificationStatus `xorm:"SMALLINT INDEX NOT NULL"`
Source NotificationSource `xorm:"SMALLINT INDEX NOT NULL"`
IssueID int64 `xorm:"INDEX NOT NULL"`
PullID int64 `xorm:"INDEX"`
CommitID string `xorm:"INDEX"`
Issue *Issue `xorm:"-"`
PullRequest *PullRequest `xorm:"-"`
Created time.Time `xorm:"-"`
CreatedUnix int64 `xorm:"INDEX NOT NULL"`
Updated time.Time `xorm:"-"`
UpdatedUnix int64 `xorm:"INDEX NOT NULL"`
}
// BeforeInsert runs while inserting a record
func (n *Notification) BeforeInsert() {
var (
now = time.Now()
nowUnix = now.Unix()
)
n.Created = now
n.CreatedUnix = nowUnix
n.Updated = now
n.UpdatedUnix = nowUnix
}
// BeforeUpdate runs while updateing a record
func (n *Notification) BeforeUpdate() {
var (
now = time.Now()
nowUnix = now.Unix()
)
n.Updated = now
n.UpdatedUnix = nowUnix
}
// CreateOrUpdateIssueNotifications creates an issue notification
// for each watcher, or updates it if already exists
func CreateOrUpdateIssueNotifications(issue *Issue) error {
watches, err := getWatchers(x, issue.RepoID)
if err != nil {
return err
}
sess := x.NewSession()
if err := sess.Begin(); err != nil {
return err
}
defer sess.Close()
for _, watch := range watches {
exists, err := issueNotificationExists(sess, watch.UserID, issue.ID)
if err != nil {
return err
}
if exists {
err = updateIssueNotification(sess, watch.UserID, issue.ID)
} else {
err = createIssueNotification(sess, watch.UserID, issue)
}
if err != nil {
return err
}
}
return sess.Commit()
}
func issueNotificationExists(e Engine, userID, issueID int64) (bool, error) {
count, err := e.
Where("user_id = ?", userID).
And("issue_id = ?", issueID).
Count(Notification{})
return count > 0, err
}
func createIssueNotification(e Engine, userID int64, issue *Issue) error {
notification := &Notification{
UserID: userID,
RepoID: issue.RepoID,
Status: NotificationStatusUnread,
IssueID: issue.ID,
}
if issue.IsPull {
notification.Source = NotificationSourcePullRequest
} else {
notification.Source = NotificationSourceIssue
}
_, err := e.Insert(notification)
return err
}
func updateIssueNotification(e Engine, userID, issueID int64) error {
notification, err := getIssueNotification(e, userID, issueID)
if err != nil {
return err
}
notification.Status = NotificationStatusUnread
_, err = e.Id(notification.ID).Update(notification)
return err
}
func getIssueNotification(e Engine, userID, issueID int64) (*Notification, error) {
notification := new(Notification)
_, err := e.
Where("user_id = ?", userID).
And("issue_id = ?", issueID).
Get(notification)
return notification, err
}
// NotificationsForUser returns notifications for a given user and status
func NotificationsForUser(user *User, status NotificationStatus) ([]*Notification, error) {
return notificationsForUser(x, user, status)
}
func notificationsForUser(e Engine, user *User, status NotificationStatus) (notifications []*Notification, err error) {
err = e.
Where("user_id = ?", user.ID).
And("status = ?", status).
OrderBy("updated_unix DESC").
Find(&notifications)
return
}
// GetRepo returns the repo of the notification
func (n *Notification) GetRepo() (repo *Repository, err error) {
repo = new(Repository)
_, err = x.
Where("id = ?", n.RepoID).
Get(repo)
return
}
// GetIssue returns the issue of the notification
func (n *Notification) GetIssue() (issue *Issue, err error) {
issue = new(Issue)
_, err = x.
Where("id = ?", n.IssueID).
Get(issue)
return
}

View File

@@ -10,13 +10,14 @@ import (
"os"
"strings"
"github.com/go-xorm/builder"
"github.com/go-xorm/xorm"
"code.gitea.io/gitea/modules/base"
)
var (
ErrOrgNotExist = errors.New("Organization does not exist")
// ErrOrgNotExist organization does not exist
ErrOrgNotExist = errors.New("Organization does not exist")
// ErrTeamNotExist team does not exist
ErrTeamNotExist = errors.New("Team does not exist")
)
@@ -40,7 +41,7 @@ func (org *User) GetTeam(name string) (*Team, error) {
}
func (org *User) getOwnerTeam(e Engine) (*Team, error) {
return org.getTeam(e, OWNER_TEAM)
return org.getTeam(e, ownerTeamName)
}
// GetOwnerTeam returns owner team of organization.
@@ -51,7 +52,7 @@ func (org *User) GetOwnerTeam() (*Team, error) {
func (org *User) getTeams(e Engine) error {
return e.
Where("org_id=?", org.ID).
OrderBy("CASE WHEN name LIKE '" + OWNER_TEAM + "' THEN '' ELSE name END").
OrderBy("CASE WHEN name LIKE '" + ownerTeamName + "' THEN '' ELSE name END").
Find(&org.Teams)
}
@@ -69,7 +70,7 @@ func (org *User) GetMembers() error {
var ids = make([]int64, len(ous))
for i, ou := range ous {
ids[i] = ou.Uid
ids[i] = ou.UID
}
org.Members, err = GetUsersByIDs(ids)
return err
@@ -128,7 +129,7 @@ func CreateOrganization(org, owner *User) (err error) {
// Add initial creator to organization and owner team.
if _, err = sess.Insert(&OrgUser{
Uid: owner.ID,
UID: owner.ID,
OrgID: org.ID,
IsOwner: true,
NumTeams: 1,
@@ -139,8 +140,8 @@ func CreateOrganization(org, owner *User) (err error) {
// Create default owner team.
t := &Team{
OrgID: org.ID,
LowerName: strings.ToLower(OWNER_TEAM),
Name: OWNER_TEAM,
LowerName: strings.ToLower(ownerTeamName),
Name: ownerTeamName,
Authorize: AccessModeOwner,
NumMembers: 1,
}
@@ -149,7 +150,7 @@ func CreateOrganization(org, owner *User) (err error) {
}
if _, err = sess.Insert(&TeamUser{
Uid: owner.ID,
UID: owner.ID,
OrgID: org.ID,
TeamID: t.ID,
}); err != nil {
@@ -236,7 +237,7 @@ func DeleteOrganization(org *User) (err error) {
// OrgUser represents an organization-user relation.
type OrgUser struct {
ID int64 `xorm:"pk autoincr"`
Uid int64 `xorm:"INDEX UNIQUE(s)"`
UID int64 `xorm:"INDEX UNIQUE(s)"`
OrgID int64 `xorm:"INDEX UNIQUE(s)"`
IsPublic bool
IsOwner bool
@@ -244,29 +245,29 @@ type OrgUser struct {
}
// IsOrganizationOwner returns true if given user is in the owner team.
func IsOrganizationOwner(orgId, uid int64) bool {
func IsOrganizationOwner(orgID, uid int64) bool {
has, _ := x.
Where("is_owner=?", true).
And("uid=?", uid).
And("org_id=?", orgId).
And("org_id=?", orgID).
Get(new(OrgUser))
return has
}
// IsOrganizationMember returns true if given user is member of organization.
func IsOrganizationMember(orgId, uid int64) bool {
func IsOrganizationMember(orgID, uid int64) bool {
has, _ := x.
Where("uid=?", uid).
And("org_id=?", orgId).
And("org_id=?", orgID).
Get(new(OrgUser))
return has
}
// IsPublicMembership returns true if given user public his/her membership.
func IsPublicMembership(orgId, uid int64) bool {
func IsPublicMembership(orgID, uid int64) bool {
has, _ := x.
Where("uid=?", uid).
And("org_id=?", orgId).
And("org_id=?", orgID).
And("is_public=?", true).
Get(new(OrgUser))
return has
@@ -312,7 +313,7 @@ func GetOwnedOrgsByUserID(userID int64) ([]*User, error) {
return getOwnedOrgsByUserID(sess, userID)
}
// GetOwnedOrganizationsByUserIDDesc returns a list of organizations are owned by
// GetOwnedOrgsByUserIDDesc returns a list of organizations are owned by
// given user ID, ordered descending by the given condition.
func GetOwnedOrgsByUserIDDesc(userID int64, desc string) ([]*User, error) {
sess := x.NewSession()
@@ -323,8 +324,8 @@ func GetOwnedOrgsByUserIDDesc(userID int64, desc string) ([]*User, error) {
func GetOrgUsersByUserID(uid int64, all bool) ([]*OrgUser, error) {
ous := make([]*OrgUser, 0, 10)
sess := x.
Join("LEFT", "user", `"org_user".org_id="user".id`).
Where(`"org_user".uid=?`, uid)
Join("LEFT", "user", "`org_user`.org_id=`user`.id").
Where("`org_user`.uid=?", uid)
if !all {
// Only show public organizations
sess.And("is_public=?", true)
@@ -375,7 +376,7 @@ func AddOrgUser(orgID, uid int64) error {
}
ou := &OrgUser{
Uid: uid,
UID: uid,
OrgID: orgID,
}
@@ -499,7 +500,7 @@ func (org *User) getUserTeams(e Engine, userID int64, cols ...string) ([]*Team,
Find(&teams)
}
// GetUserTeamIDs returns of all team IDs of the organization that user is memeber of.
// GetUserTeamIDs returns of all team IDs of the organization that user is member of.
func (org *User) GetUserTeamIDs(userID int64) ([]int64, error) {
teams, err := org.getUserTeams(x, userID, "team.id")
if err != nil {
@@ -513,7 +514,7 @@ func (org *User) GetUserTeamIDs(userID int64) ([]int64, error) {
return teamIDs, nil
}
// GetTeams returns all teams that belong to organization,
// GetUserTeams returns all teams that belong to user,
// and that the user has joined.
func (org *User) GetUserTeams(userID int64) ([]*Team, error) {
return org.getUserTeams(x, userID)
@@ -540,7 +541,7 @@ func (org *User) GetUserRepositories(userID int64, page, pageSize int) ([]*Repos
Select("`repository`.*").
Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
Where("(`repository`.owner_id=? AND `repository`.is_private=?)", org.ID, false).
Or("team_repo.team_id IN (?)", strings.Join(base.Int64sToStrings(teamIDs), ",")).
Or(builder.In("team_repo.team_id", teamIDs)).
GroupBy("`repository`.id").
OrderBy("updated_unix DESC").
Limit(pageSize, (page-1)*pageSize).
@@ -551,7 +552,7 @@ func (org *User) GetUserRepositories(userID int64, page, pageSize int) ([]*Repos
repoCount, err := x.
Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
Where("(`repository`.owner_id=? AND `repository`.is_private=?)", org.ID, false).
Or("team_repo.team_id IN (?)", strings.Join(base.Int64sToStrings(teamIDs), ",")).
Or(builder.In("team_repo.team_id", teamIDs)).
GroupBy("`repository`.id").
Count(&Repository{})
if err != nil {
@@ -561,7 +562,7 @@ func (org *User) GetUserRepositories(userID int64, page, pageSize int) ([]*Repos
return repos, repoCount, nil
}
// GetUserRepositories returns mirror repositories of the organization
// GetUserMirrorRepositories returns mirror repositories of the user
// that the user with the given userID has access to.
func (org *User) GetUserMirrorRepositories(userID int64) ([]*Repository, error) {
teamIDs, err := org.GetUserTeamIDs(userID)
@@ -577,7 +578,7 @@ func (org *User) GetUserMirrorRepositories(userID int64) ([]*Repository, error)
Select("`repository`.*").
Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id AND `repository`.is_mirror=?", true).
Where("(`repository`.owner_id=? AND `repository`.is_private=?)", org.ID, false).
Or("team_repo.team_id IN (?)", strings.Join(base.Int64sToStrings(teamIDs), ",")).
Or(builder.In("team_repo.team_id", teamIDs)).
GroupBy("`repository`.id").
OrderBy("updated_unix DESC").
Find(&repos)

View File

@@ -10,7 +10,7 @@ import (
"strings"
)
const OWNER_TEAM = "Owners"
const ownerTeamName = "Owners"
// Team represents a organization team.
type Team struct {
@@ -28,12 +28,12 @@ type Team struct {
// IsOwnerTeam returns true if team is owner team.
func (t *Team) IsOwnerTeam() bool {
return t.Name == OWNER_TEAM
return t.Name == ownerTeamName
}
// IsTeamMember returns true if given user is a member of team.
func (t *Team) IsMember(uid int64) bool {
return IsTeamMember(t.OrgID, t.ID, uid)
// IsMember returns true if given user is a member of team.
func (t *Team) IsMember(userID int64) bool {
return IsTeamMember(t.OrgID, t.ID, userID)
}
func (t *Team) getRepositories(e Engine) (err error) {
@@ -72,13 +72,13 @@ func (t *Team) GetMembers() (err error) {
// AddMember adds new membership of the team to the organization,
// the user will have membership to the organization automatically when needed.
func (t *Team) AddMember(uid int64) error {
return AddTeamMember(t.OrgID, t.ID, uid)
func (t *Team) AddMember(userID int64) error {
return AddTeamMember(t.OrgID, t.ID, userID)
}
// RemoveMember removes member from team of organization.
func (t *Team) RemoveMember(uid int64) error {
return RemoveTeamMember(t.OrgID, t.ID, uid)
func (t *Team) RemoveMember(userID int64) error {
return RemoveTeamMember(t.OrgID, t.ID, userID)
}
func (t *Team) hasRepository(e Engine, repoID int64) bool {
@@ -196,6 +196,7 @@ func (t *Team) RemoveRepository(repoID int64) error {
return sess.Commit()
}
// IsUsableTeamName tests if a name could be as team name
func IsUsableTeamName(name string) (err error) {
var reservedTeamNames = []string{"new"}
@@ -256,9 +257,9 @@ func NewTeam(t *Team) (err error) {
return sess.Commit()
}
func getTeam(e Engine, orgId int64, name string) (*Team, error) {
func getTeam(e Engine, orgID int64, name string) (*Team, error) {
t := &Team{
OrgID: orgId,
OrgID: orgID,
LowerName: strings.ToLower(name),
}
has, err := e.Get(t)
@@ -271,13 +272,13 @@ func getTeam(e Engine, orgId int64, name string) (*Team, error) {
}
// GetTeam returns team by given team name and organization.
func GetTeam(orgId int64, name string) (*Team, error) {
return getTeam(x, orgId, name)
func GetTeam(orgID int64, name string) (*Team, error) {
return getTeam(x, orgID, name)
}
func getTeamByID(e Engine, teamId int64) (*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 {
@@ -287,8 +288,8 @@ func getTeamByID(e Engine, teamId int64) (*Team, error) {
}
// GetTeamByID returns team by given ID.
func GetTeamByID(teamId int64) (*Team, error) {
return getTeamByID(x, teamId)
func GetTeamByID(teamID int64) (*Team, error) {
return getTeamByID(x, teamID)
}
// UpdateTeam updates information of team.
@@ -397,21 +398,21 @@ type TeamUser struct {
ID int64 `xorm:"pk autoincr"`
OrgID int64 `xorm:"INDEX"`
TeamID int64 `xorm:"UNIQUE(s)"`
Uid int64 `xorm:"UNIQUE(s)"`
UID int64 `xorm:"UNIQUE(s)"`
}
func isTeamMember(e Engine, orgID, teamID, uid int64) bool {
func isTeamMember(e Engine, orgID, teamID, userID int64) bool {
has, _ := e.
Where("org_id=?", orgID).
And("team_id=?", teamID).
And("uid=?", uid).
And("uid=?", userID).
Get(new(TeamUser))
return has
}
// IsTeamMember returns true if given user is a member of team.
func IsTeamMember(orgID, teamID, uid int64) bool {
return isTeamMember(x, orgID, teamID, uid)
func IsTeamMember(orgID, teamID, userID int64) bool {
return isTeamMember(x, orgID, teamID, userID)
}
func getTeamMembers(e Engine, teamID int64) (_ []*User, err error) {
@@ -424,8 +425,8 @@ 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 {
return nil, fmt.Errorf("get user '%d': %v", teamUsers[i].Uid, err)
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)
}
@@ -437,11 +438,11 @@ func GetTeamMembers(teamID int64) ([]*User, error) {
return getTeamMembers(x, teamID)
}
func getUserTeams(e Engine, orgId, uid int64) ([]*Team, error) {
func getUserTeams(e Engine, orgID, userID int64) ([]*Team, error) {
tus := make([]*TeamUser, 0, 5)
if err := e.
Where("uid=?", uid).
And("org_id=?", orgId).
Where("uid=?", userID).
And("org_id=?", orgID).
Find(&tus); err != nil {
return nil, err
}
@@ -461,18 +462,18 @@ func getUserTeams(e Engine, orgId, uid int64) ([]*Team, error) {
}
// GetUserTeams returns all teams that user belongs to in given organization.
func GetUserTeams(orgId, uid int64) ([]*Team, error) {
return getUserTeams(x, orgId, uid)
func GetUserTeams(orgID, userID int64) ([]*Team, error) {
return getUserTeams(x, orgID, userID)
}
// AddTeamMember adds new membership of given team to given organization,
// the user will have membership to given organization automatically when needed.
func AddTeamMember(orgID, teamID, uid int64) error {
if IsTeamMember(orgID, teamID, uid) {
func AddTeamMember(orgID, teamID, userID int64) error {
if IsTeamMember(orgID, teamID, userID) {
return nil
}
if err := AddOrgUser(orgID, uid); err != nil {
if err := AddOrgUser(orgID, userID); err != nil {
return err
}
@@ -494,7 +495,7 @@ func AddTeamMember(orgID, teamID, uid int64) error {
}
tu := &TeamUser{
Uid: uid,
UID: userID,
OrgID: orgID,
TeamID: teamID,
}
@@ -514,7 +515,7 @@ func AddTeamMember(orgID, teamID, uid int64) error {
// We make sure it exists before.
ou := new(OrgUser)
if _, err = sess.
Where("uid = ?", uid).
Where("uid = ?", userID).
And("org_id = ?", orgID).
Get(ou); err != nil {
return err
@@ -530,8 +531,8 @@ func AddTeamMember(orgID, teamID, uid int64) error {
return sess.Commit()
}
func removeTeamMember(e Engine, orgID, teamID, uid int64) error {
if !isTeamMember(e, orgID, teamID, uid) {
func removeTeamMember(e Engine, orgID, teamID, userID int64) error {
if !isTeamMember(e, orgID, teamID, userID) {
return nil
}
@@ -543,7 +544,7 @@ func removeTeamMember(e Engine, orgID, teamID, uid int64) error {
// Check if the user to delete is the last member in owner team.
if t.IsOwnerTeam() && t.NumMembers == 1 {
return ErrLastOrgOwner{UID: uid}
return ErrLastOrgOwner{UID: userID}
}
t.NumMembers--
@@ -559,7 +560,7 @@ func removeTeamMember(e Engine, orgID, teamID, uid int64) error {
}
tu := &TeamUser{
Uid: uid,
UID: userID,
OrgID: orgID,
TeamID: teamID,
}
@@ -582,7 +583,7 @@ func removeTeamMember(e Engine, orgID, teamID, uid int64) error {
// This must exist.
ou := new(OrgUser)
_, err = e.
Where("uid = ?", uid).
Where("uid = ?", userID).
And("org_id = ?", org.ID).
Get(ou)
if err != nil {
@@ -602,13 +603,13 @@ func removeTeamMember(e Engine, orgID, teamID, uid int64) error {
}
// RemoveTeamMember removes member from given team of given organization.
func RemoveTeamMember(orgID, teamID, uid int64) error {
func RemoveTeamMember(orgID, teamID, userID int64) error {
sess := x.NewSession()
defer sessionRelease(sess)
if err := sess.Begin(); err != nil {
return err
}
if err := removeTeamMember(sess, orgID, teamID, uid); err != nil {
if err := removeTeamMember(sess, orgID, teamID, userID); err != nil {
return err
}
return sess.Commit()

View File

@@ -21,17 +21,21 @@ import (
"github.com/go-xorm/xorm"
)
var PullRequestQueue = sync.NewUniqueQueue(setting.Repository.PullRequestQueueLength)
var pullRequestQueue = sync.NewUniqueQueue(setting.Repository.PullRequestQueueLength)
// PullRequestType defines pull request type
type PullRequestType int
// Enumerate all the pull request types
const (
PullRequestGitea PullRequestType = iota
PullRequestGit
)
// PullRequestStatus defines pull request status
type PullRequestStatus int
// Enumerate all the pull request status
const (
PullRequestStatusConflict PullRequestStatus = iota
PullRequestStatusChecking
@@ -65,10 +69,12 @@ type PullRequest struct {
MergedUnix int64
}
// BeforeUpdate is invoked from XORM before updating an object of this type.
func (pr *PullRequest) BeforeUpdate() {
pr.MergedUnix = pr.Merged.Unix()
}
// AfterSet is invoked from XORM after setting the value of a field of this object.
// Note: don't try to get Issue because will end up recursive querying.
func (pr *PullRequest) AfterSet(colName string, _ xorm.Cell) {
switch colName {
@@ -96,10 +102,12 @@ func (pr *PullRequest) loadAttributes(e Engine) (err error) {
return nil
}
// LoadAttributes loads pull request attributes from database
func (pr *PullRequest) LoadAttributes() error {
return pr.loadAttributes(x)
}
// LoadIssue loads issue information from database
func (pr *PullRequest) LoadIssue() (err error) {
if pr.Issue != nil {
return nil
@@ -109,11 +117,58 @@ func (pr *PullRequest) LoadIssue() (err error) {
return err
}
// This method assumes following fields have been assigned with valid values:
// APIFormat assumes following fields have been assigned with valid values:
// Required - Issue
// Optional - Merger
func (pr *PullRequest) APIFormat() *api.PullRequest {
var (
baseBranch *Branch
headBranch *Branch
baseCommit *git.Commit
headCommit *git.Commit
err error
)
apiIssue := pr.Issue.APIFormat()
if pr.BaseRepo == nil {
pr.BaseRepo, err = GetRepositoryByID(pr.BaseRepoID)
if err != nil {
log.Error(log.ERROR, "GetRepositoryById[%d]: %v", pr.ID, err)
return nil
}
}
if pr.HeadRepo == nil {
pr.HeadRepo, err = GetRepositoryByID(pr.HeadRepoID)
if err != nil {
log.Error(log.ERROR, "GetRepositoryById[%d]: %v", pr.ID, err)
return nil
}
}
if baseBranch, err = pr.BaseRepo.GetBranch(pr.BaseBranch); err != nil {
return nil
}
if baseCommit, err = baseBranch.GetCommit(); err != nil {
return nil
}
if headBranch, err = pr.HeadRepo.GetBranch(pr.HeadBranch); err != nil {
return nil
}
if headCommit, err = headBranch.GetCommit(); err != nil {
return nil
}
apiBaseBranchInfo := &api.PRBranchInfo{
Name: pr.BaseBranch,
Ref: pr.BaseBranch,
Sha: baseCommit.ID.String(),
RepoID: pr.BaseRepoID,
Repository: pr.BaseRepo.APIFormat(AccessModeNone),
}
apiHeadBranchInfo := &api.PRBranchInfo{
Name: pr.HeadBranch,
Ref: pr.HeadBranch,
Sha: headCommit.ID.String(),
RepoID: pr.HeadRepoID,
Repository: pr.HeadRepo.APIFormat(AccessModeNone),
}
apiPullRequest := &api.PullRequest{
ID: pr.ID,
Index: pr.Index,
@@ -126,12 +181,17 @@ func (pr *PullRequest) APIFormat() *api.PullRequest {
State: apiIssue.State,
Comments: apiIssue.Comments,
HTMLURL: pr.Issue.HTMLURL(),
DiffURL: pr.Issue.DiffURL(),
PatchURL: pr.Issue.PatchURL(),
HasMerged: pr.HasMerged,
Base: apiBaseBranchInfo,
Head: apiHeadBranchInfo,
MergeBase: pr.MergeBase,
}
if pr.Status != PullRequestStatusChecking {
mergeable := pr.Status != PullRequestStatusConflict
apiPullRequest.Mergeable = &mergeable
apiPullRequest.Mergeable = mergeable
}
if pr.HasMerged {
apiPullRequest.Merged = &pr.Merged
@@ -150,10 +210,12 @@ func (pr *PullRequest) getHeadRepo(e Engine) (err error) {
return nil
}
// GetHeadRepo loads the head repository
func (pr *PullRequest) GetHeadRepo() error {
return pr.getHeadRepo(x)
}
// GetBaseRepo loads the target repository
func (pr *PullRequest) GetBaseRepo() (err error) {
if pr.BaseRepo != nil {
return nil
@@ -208,7 +270,11 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error
// Clone base repo.
tmpBasePath := path.Join(setting.AppDataPath, "tmp/repos", com.ToStr(time.Now().Nanosecond())+".git")
os.MkdirAll(path.Dir(tmpBasePath), os.ModePerm)
if err := os.MkdirAll(path.Dir(tmpBasePath), os.ModePerm); err != nil {
return fmt.Errorf("Fail to create dir %s: %v", tmpBasePath, err)
}
defer os.RemoveAll(path.Dir(tmpBasePath))
var stderr string
@@ -289,7 +355,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error
Action: api.HookIssueClosed,
Index: pr.Index,
PullRequest: pr.APIFormat(),
Repository: pr.Issue.Repo.APIFormat(nil),
Repository: pr.Issue.Repo.APIFormat(AccessModeNone),
Sender: doer.APIFormat(),
}); err != nil {
log.Error(4, "PrepareWebhooks: %v", err)
@@ -317,9 +383,9 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error
Ref: git.BRANCH_PREFIX + pr.BaseBranch,
Before: pr.MergeBase,
After: pr.MergedCommitID,
CompareURL: setting.AppUrl + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID),
Commits: ListToPushCommits(l).ToApiPayloadCommits(pr.BaseRepo.HTMLURL()),
Repo: pr.BaseRepo.APIFormat(nil),
CompareURL: setting.AppURL + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID),
Commits: ListToPushCommits(l).ToAPIPayloadCommits(pr.BaseRepo.HTMLURL()),
Repo: pr.BaseRepo.APIFormat(AccessModeNone),
Pusher: pr.HeadRepo.MustOwner().APIFormat(),
Sender: doer.APIFormat(),
}
@@ -329,7 +395,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error
return nil
}
// patchConflicts is a list of conflit description from Git.
// patchConflicts is a list of conflict description from Git.
var patchConflicts = []string{
"patch does not apply",
"already exists in working directory",
@@ -337,7 +403,7 @@ var patchConflicts = []string{
"error:",
}
// testPatch checks if patch can be merged to base repository without conflit.
// testPatch checks if patch can be merged to base repository without conflict.
// FIXME: make a mechanism to clean up stable local copies.
func (pr *PullRequest) testPatch() (err error) {
if pr.BaseRepo == nil {
@@ -363,6 +429,9 @@ func (pr *PullRequest) testPatch() (err error) {
log.Trace("PullRequest[%d].testPatch (patchPath): %s", pr.ID, patchPath)
// Delete old temp local copy before we create a new temp local copy
RemoveAllWithNotice("Deleting old local copy", pr.BaseRepo.LocalCopyPath())
if err := pr.BaseRepo.UpdateLocalCopyBranch(pr.BaseBranch); err != nil {
return fmt.Errorf("UpdateLocalCopy: %v", err)
}
@@ -374,7 +443,7 @@ func (pr *PullRequest) testPatch() (err error) {
if err != nil {
for i := range patchConflicts {
if strings.Contains(stderr, patchConflicts[i]) {
log.Trace("PullRequest[%d].testPatch (apply): has conflit", pr.ID)
log.Trace("PullRequest[%d].testPatch (apply): has conflict", pr.ID)
fmt.Println(stderr)
pr.Status = PullRequestStatusConflict
return nil
@@ -448,7 +517,7 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str
Action: api.HookIssueOpened,
Index: pull.Index,
PullRequest: pr.APIFormat(),
Repository: repo.APIFormat(nil),
Repository: repo.APIFormat(AccessModeNone),
Sender: pull.Poster.APIFormat(),
}); err != nil {
log.Error(4, "PrepareWebhooks: %v", err)
@@ -458,6 +527,46 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str
return nil
}
// PullRequestsOptions holds the options for PRs
type PullRequestsOptions struct {
Page int
State string
SortType string
Labels []string
MilestoneID int64
}
func listPullRequestStatement(baseRepoID int64, opts *PullRequestsOptions) *xorm.Session {
sess := x.Where("pull_request.base_repo_id=?", baseRepoID)
sess.Join("INNER", "issue", "pull_request.issue_id = issue.id")
switch opts.State {
case "closed", "open":
sess.And("issue.is_closed=?", opts.State == "closed")
}
return sess
}
// PullRequests returns all pull requests for a base Repo by the given conditions
func PullRequests(baseRepoID int64, opts *PullRequestsOptions) ([]*PullRequest, int64, error) {
if opts.Page <= 0 {
opts.Page = 1
}
countSession := listPullRequestStatement(baseRepoID, opts)
maxResults, err := countSession.Count(new(PullRequest))
if err != nil {
log.Error(4, "Count PRs", err)
return nil, maxResults, err
}
prs := make([]*PullRequest, 0, ItemsPerPage)
findSession := listPullRequestStatement(baseRepoID, opts)
findSession.Limit(ItemsPerPage, (opts.Page-1)*ItemsPerPage)
return prs, maxResults, findSession.Find(&prs)
}
// GetUnmergedPullRequest returnss a pull request that is open and has not been merged
// by given head/base and repo/branch.
func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch string) (*PullRequest, error) {
@@ -498,6 +607,30 @@ func GetUnmergedPullRequestsByBaseInfo(repoID int64, branch string) ([]*PullRequ
Find(&prs)
}
// GetPullRequestByIndex returns a pull request by the given index
func GetPullRequestByIndex(repoID int64, index int64) (*PullRequest, error) {
pr := &PullRequest{
BaseRepoID: repoID,
Index: index,
}
has, err := x.Get(pr)
if err != nil {
return nil, err
} else if !has {
return nil, ErrPullRequestNotExist{0, repoID, index, 0, "", ""}
}
if err = pr.LoadAttributes(); err != nil {
return nil, err
}
if err = pr.LoadIssue(); err != nil {
return nil, err
}
return pr, nil
}
func getPullRequestByID(e Engine, id int64) (*PullRequest, error) {
pr := new(PullRequest)
has, err := e.Id(id).Get(pr)
@@ -538,7 +671,7 @@ func (pr *PullRequest) Update() error {
return err
}
// Update updates specific fields of pull request.
// UpdateCols updates specific fields of pull request.
func (pr *PullRequest) UpdateCols(cols ...string) error {
_, err := x.Id(pr.ID).Cols(cols...).Update(pr)
return err
@@ -612,7 +745,9 @@ func (pr *PullRequest) PushToBaseRepo() (err error) {
headFile := fmt.Sprintf("refs/pull/%d/head", pr.Index)
// Remove head in case there is a conflict.
os.Remove(path.Join(pr.BaseRepo.RepoPath(), headFile))
file := path.Join(pr.BaseRepo.RepoPath(), headFile)
_ = os.Remove(file)
if err = git.Push(headRepoPath, tmpRemoteName, fmt.Sprintf("%s:%s", pr.HeadBranch, headFile)); err != nil {
return fmt.Errorf("Push: %v", err)
@@ -623,7 +758,7 @@ func (pr *PullRequest) PushToBaseRepo() (err error) {
// AddToTaskQueue adds itself to pull request test task queue.
func (pr *PullRequest) AddToTaskQueue() {
go PullRequestQueue.AddFunc(pr.ID, func() {
go pullRequestQueue.AddFunc(pr.ID, func() {
pr.Status = PullRequestStatusChecking
if err := pr.UpdateCols("status"); err != nil {
log.Error(5, "AddToTaskQueue.UpdateCols[%d].(add to queue): %v", pr.ID, err)
@@ -631,6 +766,7 @@ func (pr *PullRequest) AddToTaskQueue() {
})
}
// PullRequestList defines a list of pull requests
type PullRequestList []*PullRequest
func (prs PullRequestList) loadAttributes(e Engine) error {
@@ -661,6 +797,7 @@ func (prs PullRequestList) loadAttributes(e Engine) error {
return nil
}
// LoadAttributes load all the prs attributes
func (prs PullRequestList) LoadAttributes() error {
return prs.loadAttributes(x)
}
@@ -706,7 +843,7 @@ func AddTestPullRequestTask(doer *User, repoID int64, branch string, isSync bool
Action: api.HookIssueSynchronized,
Index: pr.Issue.Index,
PullRequest: pr.Issue.PullRequest.APIFormat(),
Repository: pr.Issue.Repo.APIFormat(nil),
Repository: pr.Issue.Repo.APIFormat(AccessModeNone),
Sender: doer.APIFormat(),
}); err != nil {
log.Error(4, "PrepareWebhooks [pull_id: %v]: %v", pr.ID, err)
@@ -730,6 +867,7 @@ func AddTestPullRequestTask(doer *User, repoID int64, branch string, isSync bool
}
}
// ChangeUsernameInPullRequests changes the name of head_user_name
func ChangeUsernameInPullRequests(oldUserName, newUserName string) error {
pr := PullRequest{
HeadUserName: strings.ToLower(newUserName),
@@ -750,7 +888,7 @@ func (pr *PullRequest) checkAndUpdateStatus() {
}
// Make sure there is no waiting test to process before levaing the checking status.
if !PullRequestQueue.Exist(pr.ID) {
if !pullRequestQueue.Exist(pr.ID) {
if err := pr.UpdateCols("status"); err != nil {
log.Error(4, "Update[%d]: %v", pr.ID, err)
}
@@ -786,9 +924,9 @@ func TestPullRequests() {
}
// Start listening on new test requests.
for prID := range PullRequestQueue.Queue() {
for prID := range pullRequestQueue.Queue() {
log.Trace("TestPullRequests[%v]: processing test task", prID)
PullRequestQueue.Remove(prID)
pullRequestQueue.Remove(prID)
pr, err := GetPullRequestByID(com.StrTo(prID).MustInt64())
if err != nil {
@@ -803,6 +941,7 @@ func TestPullRequests() {
}
}
// InitTestPullRequests runs the task to test all the checking status pull requests
func InitTestPullRequests() {
go TestPullRequests()
}

View File

@@ -38,12 +38,14 @@ type Release struct {
CreatedUnix int64
}
// BeforeInsert is invoked from XORM before inserting an object of this type.
func (r *Release) BeforeInsert() {
if r.CreatedUnix == 0 {
r.CreatedUnix = time.Now().Unix()
}
}
// AfterSet is invoked from XORM after setting the value of a field of this object.
func (r *Release) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created_unix":
@@ -151,15 +153,15 @@ func GetReleasesByRepoID(repoID int64, page, pageSize int) (rels []*Release, err
return rels, err
}
type ReleaseSorter struct {
type releaseSorter struct {
rels []*Release
}
func (rs *ReleaseSorter) Len() int {
func (rs *releaseSorter) Len() int {
return len(rs.rels)
}
func (rs *ReleaseSorter) Less(i, j int) bool {
func (rs *releaseSorter) Less(i, j int) bool {
diffNum := rs.rels[i].NumCommits - rs.rels[j].NumCommits
if diffNum != 0 {
return diffNum > 0
@@ -167,13 +169,13 @@ func (rs *ReleaseSorter) Less(i, j int) bool {
return rs.rels[i].Created.After(rs.rels[j].Created)
}
func (rs *ReleaseSorter) Swap(i, j int) {
func (rs *releaseSorter) Swap(i, j int) {
rs.rels[i], rs.rels[j] = rs.rels[j], rs.rels[i]
}
// SortReleases sorts releases by number of commits and created time.
func SortReleases(rels []*Release) {
sorter := &ReleaseSorter{rels: rels}
sorter := &releaseSorter{rels: rels}
sort.Sort(sorter)
}

View File

@@ -41,20 +41,40 @@ const (
var repoWorkingPool = sync.NewExclusivePool()
var (
ErrRepoFileNotExist = errors.New("Repository file does not exist")
// ErrRepoFileNotExist repository file does not exist error
ErrRepoFileNotExist = errors.New("Repository file does not exist")
// ErrRepoFileNotLoaded repository file not loaded error
ErrRepoFileNotLoaded = errors.New("Repository file not loaded")
ErrMirrorNotExist = errors.New("Mirror does not exist")
ErrInvalidReference = errors.New("Invalid reference specified")
ErrNameEmpty = errors.New("Name is empty")
// ErrMirrorNotExist mirror does not exist error
ErrMirrorNotExist = errors.New("Mirror does not exist")
// ErrInvalidReference invalid reference specified error
ErrInvalidReference = errors.New("Invalid reference specified")
// ErrNameEmpty name is empty error
ErrNameEmpty = errors.New("Name is empty")
)
var (
Gitignores, Licenses, Readmes, LabelTemplates []string
// Gitignores contains the gitiginore files
Gitignores []string
// Maximum items per page in forks, watchers and stars of a repo
// Licenses contains the license files
Licenses []string
// Readmes contains the readme files
Readmes []string
// LabelTemplates contains the label template files
LabelTemplates []string
// ItemsPerPage maximum items per page in forks, watchers and stars of a repo
ItemsPerPage = 40
)
// LoadRepoConfig loads the repository config
func LoadRepoConfig() {
// Load .gitignore and license files and readme templates.
types := []string{"gitignore", "license", "readme", "label"}
@@ -104,6 +124,7 @@ func LoadRepoConfig() {
Licenses = sortedLicenses
}
// NewRepoContext creates a new repository context
func NewRepoContext() {
zip.Verbose = false
@@ -200,15 +221,18 @@ type Repository struct {
UpdatedUnix int64
}
// BeforeInsert is invoked from XORM before inserting an object of this type.
func (repo *Repository) BeforeInsert() {
repo.CreatedUnix = time.Now().Unix()
repo.UpdatedUnix = repo.CreatedUnix
}
// BeforeUpdate is invoked from XORM before updating this object.
func (repo *Repository) BeforeUpdate() {
repo.UpdatedUnix = time.Now().Unix()
}
// AfterSet is invoked from XORM after setting the value of a field of this object.
func (repo *Repository) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "default_branch":
@@ -224,7 +248,7 @@ func (repo *Repository) AfterSet(colName string, _ xorm.Cell) {
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
case "external_tracker_style":
if len(repo.ExternalTrackerStyle) == 0 {
repo.ExternalTrackerStyle = markdown.ISSUE_NAME_STYLE_NUMERIC
repo.ExternalTrackerStyle = markdown.IssueNameStyleNumeric
}
case "created_unix":
repo.Created = time.Unix(repo.CreatedUnix, 0).Local()
@@ -241,17 +265,24 @@ func (repo *Repository) MustOwner() *User {
return repo.mustOwner(x)
}
// FullName returns the repository full name
func (repo *Repository) FullName() string {
return repo.MustOwner().Name + "/" + repo.Name
}
// HTMLURL returns the repository HTML URL
func (repo *Repository) HTMLURL() string {
return setting.AppUrl + repo.FullName()
return setting.AppURL + repo.FullName()
}
// Arguments that are allowed to be nil: permission
func (repo *Repository) APIFormat(permission *api.Permission) *api.Repository {
// APIFormat converts a Repository to api.Repository
func (repo *Repository) APIFormat(mode AccessMode) *api.Repository {
cloneLink := repo.CloneLink()
permission := &api.Permission{
Admin: mode >= AccessModeAdmin,
Push: mode >= AccessModeWrite,
Pull: mode >= AccessModeRead,
}
return &api.Repository{
ID: repo.ID,
Owner: repo.Owner.APIFormat(),
@@ -284,6 +315,7 @@ func (repo *Repository) getOwner(e Engine) (err error) {
return err
}
// GetOwner returns the repository owner
func (repo *Repository) GetOwner() error {
return repo.getOwner(x)
}
@@ -310,10 +342,10 @@ func (repo *Repository) ComposeMetas() map[string]string {
"repo": repo.Name,
}
switch repo.ExternalTrackerStyle {
case markdown.ISSUE_NAME_STYLE_ALPHANUMERIC:
repo.ExternalMetas["style"] = markdown.ISSUE_NAME_STYLE_ALPHANUMERIC
case markdown.IssueNameStyleAlphanumeric:
repo.ExternalMetas["style"] = markdown.IssueNameStyleAlphanumeric
default:
repo.ExternalMetas["style"] = markdown.ISSUE_NAME_STYLE_NUMERIC
repo.ExternalMetas["style"] = markdown.IssueNameStyleNumeric
}
}
@@ -381,11 +413,13 @@ func (repo *Repository) IssueStats(uid int64, filterMode int, isPull bool) (int6
return GetRepoIssueStats(repo.ID, uid, filterMode, isPull)
}
// GetMirror sets the repository mirror, returns an error upon failure
func (repo *Repository) GetMirror() (err error) {
repo.Mirror, err = GetMirrorByRepoID(repo.ID)
return err
}
// GetBaseRepo returns the base repository
func (repo *Repository) GetBaseRepo() (err error) {
if !repo.IsFork {
return nil
@@ -399,31 +433,38 @@ func (repo *Repository) repoPath(e Engine) string {
return RepoPath(repo.mustOwner(e).Name, repo.Name)
}
// RepoPath returns the repository path
func (repo *Repository) RepoPath() string {
return repo.repoPath(x)
}
// GitConfigPath returns the repository git config path
func (repo *Repository) GitConfigPath() string {
return filepath.Join(repo.RepoPath(), "config")
}
// RelLink returns the repository relative link
func (repo *Repository) RelLink() string {
return "/" + repo.FullName()
}
// Link returns the repository link
func (repo *Repository) Link() string {
return setting.AppSubUrl + "/" + repo.FullName()
return setting.AppSubURL + "/" + repo.FullName()
}
// ComposeCompareURL returns the repository comparison URL
func (repo *Repository) ComposeCompareURL(oldCommitID, newCommitID string) string {
return fmt.Sprintf("%s/%s/compare/%s...%s", repo.MustOwner().Name, repo.Name, oldCommitID, newCommitID)
}
// HasAccess returns true when user has access to this repository
func (repo *Repository) HasAccess(u *User) bool {
has, _ := HasAccess(u, repo, AccessModeRead)
return has
}
// IsOwnedBy returns true when user owns this repository
func (repo *Repository) IsOwnedBy(userID int64) bool {
return repo.OwnerID == userID
}
@@ -438,7 +479,7 @@ func (repo *Repository) CanEnablePulls() bool {
return !repo.IsMirror
}
// AllowPulls returns true if repository meets the requirements of accepting pulls and has them enabled.
// AllowsPulls returns true if repository meets the requirements of accepting pulls and has them enabled.
func (repo *Repository) AllowsPulls() bool {
return repo.CanEnablePulls() && repo.EnablePulls
}
@@ -448,6 +489,7 @@ func (repo *Repository) CanEnableEditor() bool {
return !repo.IsMirror
}
// NextIssueIndex returns the next issue index
// FIXME: should have a mutex to prevent producing same index for two issues that are created
// closely enough.
func (repo *Repository) NextIssueIndex() int64 {
@@ -455,22 +497,23 @@ func (repo *Repository) NextIssueIndex() int64 {
}
var (
DescPattern = regexp.MustCompile(`https?://\S+`)
descPattern = regexp.MustCompile(`https?://\S+`)
)
// DescriptionHtml does special handles to description and return HTML string.
func (repo *Repository) DescriptionHtml() template.HTML {
// DescriptionHTML does special handles to description and return HTML string.
func (repo *Repository) DescriptionHTML() template.HTML {
sanitize := func(s string) string {
return fmt.Sprintf(`<a href="%[1]s" target="_blank">%[1]s</a>`, s)
return fmt.Sprintf(`<a href="%[1]s" target="_blank" rel="noopener">%[1]s</a>`, s)
}
return template.HTML(DescPattern.ReplaceAllStringFunc(markdown.Sanitizer.Sanitize(repo.Description), sanitize))
return template.HTML(descPattern.ReplaceAllStringFunc(markdown.Sanitizer.Sanitize(repo.Description), sanitize))
}
// LocalCopyPath returns the local repository copy path
func (repo *Repository) LocalCopyPath() string {
return path.Join(setting.AppDataPath, "tmp/local-rpeo", com.ToStr(repo.ID))
}
// UpdateLocalCopy pulls latest changes of given branch from repoPath to localPath.
// UpdateLocalCopyBranch pulls latest changes of given branch from repoPath to localPath.
// It creates a new clone if local copy does not exist.
// This function checks out target branch by default, it is safe to assume subsequent
// operations are operating against target branch when caller has confidence for no race condition.
@@ -519,8 +562,12 @@ func (repo *Repository) SavePatch(index int64, patch []byte) error {
if err != nil {
return fmt.Errorf("PatchPath: %v", err)
}
dir := filepath.Dir(patchPath)
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return fmt.Errorf("Fail to create dir %s: %v", dir, err)
}
os.MkdirAll(filepath.Dir(patchPath), os.ModePerm)
if err = ioutil.WriteFile(patchPath, patch, 0644); err != nil {
return fmt.Errorf("WriteFile: %v", err)
}
@@ -550,7 +597,7 @@ type CloneLink struct {
// ComposeHTTPSCloneURL returns HTTPS clone URL based on given owner and repository name.
func ComposeHTTPSCloneURL(owner, repo string) string {
return fmt.Sprintf("%s%s/%s.git", setting.AppUrl, owner, repo)
return fmt.Sprintf("%s%s/%s.git", setting.AppURL, owner, repo)
}
func (repo *Repository) cloneLink(isWiki bool) *CloneLink {
@@ -575,6 +622,7 @@ func (repo *Repository) CloneLink() (cl *CloneLink) {
return repo.cloneLink(false)
}
// MigrateRepoOptions contains the repository migrate options
type MigrateRepoOptions struct {
Name string
Description string
@@ -629,7 +677,10 @@ func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) {
migrateTimeout := time.Duration(setting.Git.Timeout.Migrate) * time.Second
os.RemoveAll(repoPath)
if err := os.RemoveAll(repoPath); err != nil {
return repo, fmt.Errorf("Fail to remove %s: %v", repoPath, err)
}
if err = git.Clone(opts.RemoteAddr, repoPath, git.CloneRepoOptions{
Mirror: true,
Quiet: true,
@@ -640,7 +691,11 @@ func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) {
wikiRemotePath := wikiRemoteURL(opts.RemoteAddr)
if len(wikiRemotePath) > 0 {
os.RemoveAll(wikiPath)
if err := os.RemoveAll(wikiPath); err != nil {
return repo, fmt.Errorf("Fail to remove %s: %v", wikiPath, err)
}
if err = git.Clone(wikiRemotePath, wikiPath, git.CloneRepoOptions{
Mirror: true,
Quiet: true,
@@ -711,7 +766,7 @@ func createUpdateHook(repoPath string) error {
fmt.Sprintf(tplUpdateHook, setting.ScriptType, "\""+setting.AppPath+"\"", setting.CustomConf))
}
// Finish migrating repository and/or wiki with things that don't need to be done for mirrors.
// CleanUpMigrateInfo finishes migrating repository and/or wiki with things that don't need to be done for mirrors.
func CleanUpMigrateInfo(repo *Repository) (*Repository, error) {
repoPath := repo.RepoPath()
if err := createUpdateHook(repoPath); err != nil {
@@ -759,6 +814,7 @@ func initRepoCommit(tmpPath string, sig *git.Signature) (err error) {
return nil
}
// CreateRepoOptions contains the create repository options
type CreateRepoOptions struct {
Name string
Description string
@@ -861,7 +917,11 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts C
// Initialize repository according to user's choice.
if opts.AutoInit {
os.MkdirAll(tmpDir, os.ModePerm)
if err := os.MkdirAll(tmpDir, os.ModePerm); err != nil {
return fmt.Errorf("Fail to create dir %s: %v", tmpDir, err)
}
defer os.RemoveAll(tmpDir)
if err = prepareRepoCommit(repo, tmpDir, repoPath, opts); err != nil {
@@ -897,6 +957,7 @@ var (
reservedRepoPatterns = []string{"*.git", "*.wiki"}
)
// IsUsableRepoName returns true when repository is usable
func IsUsableRepoName(name string) error {
return isUsableName(reservedRepoNames, reservedRepoPatterns, name)
}
@@ -1030,6 +1091,7 @@ func CountUserRepositories(userID int64, private bool) int64 {
return countRepositories(userID, private)
}
// Repositories returns all repositories
func Repositories(page, pageSize int) (_ []*Repository, err error) {
repos := make([]*Repository, 0, pageSize)
return repos, x.Limit(pageSize, (page-1)*pageSize).Asc("id").Find(&repos)
@@ -1155,7 +1217,12 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
}
// Rename remote repository to new path and delete local copy.
os.MkdirAll(UserPath(newOwner.Name), os.ModePerm)
dir := UserPath(newOwner.Name)
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return fmt.Errorf("Fail to create dir %s: %v", dir, err)
}
if err = os.Rename(RepoPath(owner.Name, repo.Name), RepoPath(newOwner.Name, repo.Name)); err != nil {
return fmt.Errorf("rename repository directory: %v", err)
}
@@ -1275,6 +1342,7 @@ func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err e
return nil
}
// UpdateRepository updates a repository
func UpdateRepository(repo *Repository, visibilityChanged bool) (err error) {
sess := x.NewSession()
defer sessionRelease(sess)
@@ -1474,7 +1542,7 @@ func GetUserRepositories(userID int64, private bool, page, pageSize int) ([]*Rep
return repos, sess.Find(&repos)
}
// GetUserRepositories returns a list of mirror repositories of given user.
// GetUserMirrorRepositories returns a list of mirror repositories of given user.
func GetUserMirrorRepositories(userID int64) ([]*Repository, error) {
repos := make([]*Repository, 0, 10)
return repos, x.
@@ -1502,6 +1570,7 @@ func GetRepositoryCount(u *User) (int64, error) {
return getRepositoryCount(x, u)
}
// SearchRepoOptions holds the search options
type SearchRepoOptions struct {
Keyword string
OwnerID int64
@@ -1670,6 +1739,7 @@ func GitFsck() {
}
}
// GitGcRepos calls 'git gc' to remove unnecessary files and optimize the local repository
func GitGcRepos() error {
args := append([]string{"gc"}, setting.Git.GCArgs...)
return x.
@@ -1712,6 +1782,7 @@ func repoStatsCheck(checker *repoChecker) {
}
}
// CheckRepoStats checks the repository stats
func CheckRepoStats() {
if taskStatusTable.IsRunning(checkRepos) {
return
@@ -1806,6 +1877,7 @@ func CheckRepoStats() {
// ***** END: Repository.NumForks *****
}
// RepositoryList contains a list of repositories
type RepositoryList []*Repository
func (repos RepositoryList) loadAttributes(e Engine) error {
@@ -1838,10 +1910,12 @@ func (repos RepositoryList) loadAttributes(e Engine) error {
return nil
}
// LoadAttributes loads the attributes for the given RepositoryList
func (repos RepositoryList) LoadAttributes() error {
return repos.loadAttributes(x)
}
// MirrorRepositoryList contains the mirror repositories
type MirrorRepositoryList []*Repository
func (repos MirrorRepositoryList) loadAttributes(e Engine) error {
@@ -1876,6 +1950,7 @@ func (repos MirrorRepositoryList) loadAttributes(e Engine) error {
return nil
}
// LoadAttributes loads the attributes for the given MirrorRepositoryList
func (repos MirrorRepositoryList) LoadAttributes() error {
return repos.loadAttributes(x)
}
@@ -1925,7 +2000,7 @@ func watchRepo(e Engine, userID, repoID int64, watch bool) (err error) {
return err
}
// Watch or unwatch repository.
// WatchRepo watch or unwatch repository.
func WatchRepo(userID, repoID int64, watch bool) (err error) {
return watchRepo(x, userID, repoID, watch)
}
@@ -1940,7 +2015,7 @@ func GetWatchers(repoID int64) ([]*Watch, error) {
return getWatchers(x, repoID)
}
// Repository.GetWatchers returns range of users watching given repository.
// GetWatchers returns range of users watching given repository.
func (repo *Repository) GetWatchers(page int) ([]*User, error) {
users := make([]*User, 0, ItemsPerPage)
sess := x.
@@ -1993,13 +2068,14 @@ func NotifyWatchers(act *Action) error {
// /_______ /|__| (____ /__|
// \/ \/
// Star contains the star information
type Star struct {
ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"UNIQUE(s)"`
RepoID int64 `xorm:"UNIQUE(s)"`
}
// Star or unstar repository.
// StarRepo star or unstar repository.
func StarRepo(userID, repoID int64, star bool) (err error) {
if star {
if IsStaring(userID, repoID) {
@@ -2031,6 +2107,7 @@ func IsStaring(userID, repoID int64) bool {
return has
}
// GetStargazers returns the users who gave stars to this repository
func (repo *Repository) GetStargazers(page int) ([]*User, error) {
users := make([]*User, 0, ItemsPerPage)
sess := x.
@@ -2060,6 +2137,7 @@ func HasForkedRepo(ownerID, repoID int64) (*Repository, bool) {
return repo, has
}
// ForkRepository forks a repository
func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) {
repo := &Repository{
OwnerID: u.ID,
@@ -2099,7 +2177,7 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Reposit
repoPath, fmt.Sprintf("ForkRepository(git update-server-info): %s", repoPath),
"git", "update-server-info")
if err != nil {
return nil, fmt.Errorf("git update-server-info: %v", err)
return nil, fmt.Errorf("git update-server-info: %v", stderr)
}
if err = createUpdateHook(repoPath); err != nil {
@@ -2109,6 +2187,7 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Reposit
return repo, sess.Commit()
}
// GetForks returns all the forks of the repository
func (repo *Repository) GetForks() ([]*Repository, error) {
forks := make([]*Repository, 0, repo.NumForks)
return forks, x.Find(&forks, &Repository{ForkID: repo.ID})
@@ -2122,6 +2201,7 @@ func (repo *Repository) GetForks() ([]*Repository, error) {
// \/ \/ \/ \/ \/
//
// CreateNewBranch creates a new repository branch
func (repo *Repository) CreateNewBranch(doer *User, oldBranchName, branchName string) (err error) {
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))

View File

@@ -8,11 +8,13 @@ import (
"code.gitea.io/git"
)
// Branch holds the branch information
type Branch struct {
Path string
Name string
}
// GetBranchesByPath returns a branch by it's path
func GetBranchesByPath(path string) ([]*Branch, error) {
gitRepo, err := git.OpenRepository(path)
if err != nil {
@@ -34,24 +36,27 @@ func GetBranchesByPath(path string) ([]*Branch, error) {
return branches, nil
}
func (repo *Repository) GetBranch(br string) (*Branch, error) {
if !git.IsBranchExist(repo.RepoPath(), br) {
return nil, &ErrBranchNotExist{br}
// GetBranch returns a branch by it's name
func (repo *Repository) GetBranch(branch string) (*Branch, error) {
if !git.IsBranchExist(repo.RepoPath(), branch) {
return nil, &ErrBranchNotExist{branch}
}
return &Branch{
Path: repo.RepoPath(),
Name: br,
Name: branch,
}, nil
}
// GetBranches returns all the branches of a repository
func (repo *Repository) GetBranches() ([]*Branch, error) {
return GetBranchesByPath(repo.RepoPath())
}
func (br *Branch) GetCommit() (*git.Commit, error) {
gitRepo, err := git.OpenRepository(br.Path)
// GetCommit returns all the commits of a branch
func (branch *Branch) GetCommit() (*git.Commit, error) {
gitRepo, err := git.OpenRepository(branch.Path)
if err != nil {
return nil, err
}
return gitRepo.GetBranchCommit(br.Name)
return gitRepo.GetBranchCommit(branch.Name)
}

View File

@@ -16,6 +16,7 @@ type Collaboration struct {
Mode AccessMode `xorm:"DEFAULT 2 NOT NULL"`
}
// ModeI18nKey returns the collaboration mode I18n Key
func (c *Collaboration) ModeI18nKey() string {
switch c.Mode {
case AccessModeRead:
@@ -67,7 +68,7 @@ func (repo *Repository) AddCollaborator(u *User) error {
}
func (repo *Repository) getCollaborations(e Engine) ([]*Collaboration, error) {
collaborations := make([]*Collaboration, 0)
var collaborations []*Collaboration
return collaborations, e.Find(&collaborations, &Collaboration{RepoID: repo.ID})
}

View File

@@ -50,6 +50,7 @@ func discardLocalRepoBranchChanges(localPath, branch string) error {
return nil
}
// DiscardLocalRepoBranchChanges discards the local repository branch changes
func (repo *Repository) DiscardLocalRepoBranchChanges(branch string) error {
return discardLocalRepoBranchChanges(repo.LocalCopyPath(), branch)
}
@@ -66,10 +67,12 @@ func checkoutNewBranch(repoPath, localPath, oldBranch, newBranch string) error {
return nil
}
// CheckoutNewBranch checks out a new branch
func (repo *Repository) CheckoutNewBranch(oldBranch, newBranch string) error {
return checkoutNewBranch(repo.RepoPath(), repo.LocalCopyPath(), oldBranch, newBranch)
}
// UpdateRepoFileOptions holds the repository file update options
type UpdateRepoFileOptions struct {
LastCommitID string
OldBranch string
@@ -101,7 +104,11 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
localPath := repo.LocalCopyPath()
oldFilePath := path.Join(localPath, opts.OldTreeName)
filePath := path.Join(localPath, opts.NewTreeName)
os.MkdirAll(path.Dir(filePath), os.ModePerm)
dir := path.Dir(filePath)
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return fmt.Errorf("Fail to create dir %s: %v", dir, err)
}
// If it's meant to be a new file, make sure it doesn't exist.
if opts.IsNewFile {
@@ -182,7 +189,12 @@ func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *
localPath := repo.LocalCopyPath()
filePath := path.Join(localPath, treePath)
os.MkdirAll(filepath.Dir(filePath), os.ModePerm)
dir := filepath.Dir(filePath)
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return nil, fmt.Errorf("Fail to create dir %s: %v", dir, err)
}
if err = ioutil.WriteFile(filePath, []byte(content), 0666); err != nil {
return nil, fmt.Errorf("WriteFile: %v", err)
}
@@ -223,6 +235,7 @@ func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *
// \/ \/ \/ \/ \/ \/
//
// DeleteRepoFileOptions holds the repository delete file options
type DeleteRepoFileOptions struct {
LastCommitID string
OldBranch string
@@ -231,6 +244,7 @@ type DeleteRepoFileOptions struct {
Message string
}
// DeleteRepoFile deletes a repository file
func (repo *Repository) DeleteRepoFile(doer *User, opts DeleteRepoFileOptions) (err error) {
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
@@ -351,6 +365,7 @@ func NewUpload(name string, buf []byte, file multipart.File) (_ *Upload, err err
return upload, nil
}
// GetUploadByUUID returns the Upload by UUID
func GetUploadByUUID(uuid string) (*Upload, error) {
upload := &Upload{UUID: uuid}
has, err := x.Get(upload)
@@ -362,6 +377,7 @@ func GetUploadByUUID(uuid string) (*Upload, error) {
return upload, nil
}
// GetUploadsByUUIDs returns multiple uploads by UUIDS
func GetUploadsByUUIDs(uuids []string) ([]*Upload, error) {
if len(uuids) == 0 {
return []*Upload{}, nil
@@ -372,6 +388,7 @@ func GetUploadsByUUIDs(uuids []string) ([]*Upload, error) {
return uploads, x.In("uuid", uuids).Find(&uploads)
}
// DeleteUploads deletes multiple uploads
func DeleteUploads(uploads ...*Upload) (err error) {
if len(uploads) == 0 {
return nil
@@ -407,10 +424,12 @@ func DeleteUploads(uploads ...*Upload) (err error) {
return sess.Commit()
}
// DeleteUpload delete a upload
func DeleteUpload(u *Upload) error {
return DeleteUploads(u)
}
// DeleteUploadByUUID deletes a upload by UUID
func DeleteUploadByUUID(uuid string) error {
upload, err := GetUploadByUUID(uuid)
if err != nil {
@@ -427,6 +446,7 @@ func DeleteUploadByUUID(uuid string) error {
return nil
}
// UploadRepoFileOptions contains the uploaded repository file options
type UploadRepoFileOptions struct {
LastCommitID string
OldBranch string
@@ -436,6 +456,7 @@ type UploadRepoFileOptions struct {
Files []string // In UUID format.
}
// UploadRepoFiles uploads files to a repository
func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions) (err error) {
if len(opts.Files) == 0 {
return nil
@@ -463,7 +484,10 @@ func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions)
localPath := repo.LocalCopyPath()
dirPath := path.Join(localPath, opts.TreePath)
os.MkdirAll(dirPath, os.ModePerm)
if err := os.MkdirAll(dirPath, os.ModePerm); err != nil {
return fmt.Errorf("Fail to create dir %s: %v", dirPath, err)
}
// Copy uploaded files into repository.
for _, upload := range uploads {

View File

@@ -19,6 +19,7 @@ import (
"code.gitea.io/gitea/modules/sync"
)
// MirrorQueue holds an UniqueQueue object of the mirror
var MirrorQueue = sync.NewUniqueQueue(setting.Repository.MirrorQueueLength)
// Mirror represents mirror information of a repository.
@@ -37,16 +38,19 @@ type Mirror struct {
address string `xorm:"-"`
}
// BeforeInsert will be invoked by XORM before inserting a record
func (m *Mirror) BeforeInsert() {
m.UpdatedUnix = time.Now().Unix()
m.NextUpdateUnix = m.NextUpdate.Unix()
}
// BeforeUpdate is invoked from XORM before updating this object.
func (m *Mirror) BeforeUpdate() {
m.UpdatedUnix = time.Now().Unix()
m.NextUpdateUnix = m.NextUpdate.Unix()
}
// AfterSet is invoked from XORM after setting the value of a field of this object.
func (m *Mirror) AfterSet(colName string, _ xorm.Cell) {
var err error
switch colName {
@@ -180,10 +184,12 @@ func updateMirror(e Engine, m *Mirror) error {
return err
}
// UpdateMirror updates the mirror
func UpdateMirror(m *Mirror) error {
return updateMirror(x, m)
}
// DeleteMirrorByRepoID deletes a mirror by repoID
func DeleteMirrorByRepoID(repoID int64) error {
_, err := x.Delete(&Mirror{RepoID: repoID})
return err
@@ -241,6 +247,7 @@ func SyncMirrors() {
}
}
// InitSyncMirrors initializes a go routine to sync the mirros
func InitSyncMirrors() {
go SyncMirrors()
}

View File

@@ -24,7 +24,7 @@ func TestRepo(t *testing.T) {
Convey("It should be nil even if other settings are present", func() {
repo.EnableExternalTracker = false
repo.ExternalTrackerFormat = "http://someurl.com/{user}/{repo}/{issue}"
repo.ExternalTrackerStyle = markdown.ISSUE_NAME_STYLE_NUMERIC
repo.ExternalTrackerStyle = markdown.IssueNameStyleNumeric
So(repo.ComposeMetas(), ShouldEqual, map[string]string(nil))
})
})
@@ -33,17 +33,17 @@ func TestRepo(t *testing.T) {
repo.EnableExternalTracker = true
Convey("It should default to numeric issue style", func() {
metas := repo.ComposeMetas()
So(metas["style"], ShouldEqual, markdown.ISSUE_NAME_STYLE_NUMERIC)
So(metas["style"], ShouldEqual, markdown.IssueNameStyleNumeric)
})
Convey("It should pass through numeric issue style setting", func() {
repo.ExternalTrackerStyle = markdown.ISSUE_NAME_STYLE_NUMERIC
repo.ExternalTrackerStyle = markdown.IssueNameStyleNumeric
metas := repo.ComposeMetas()
So(metas["style"], ShouldEqual, markdown.ISSUE_NAME_STYLE_NUMERIC)
So(metas["style"], ShouldEqual, markdown.IssueNameStyleNumeric)
})
Convey("It should pass through alphanumeric issue style setting", func() {
repo.ExternalTrackerStyle = markdown.ISSUE_NAME_STYLE_ALPHANUMERIC
repo.ExternalTrackerStyle = markdown.IssueNameStyleAlphanumeric
metas := repo.ComposeMetas()
So(metas["style"], ShouldEqual, markdown.ISSUE_NAME_STYLE_ALPHANUMERIC)
So(metas["style"], ShouldEqual, markdown.IssueNameStyleAlphanumeric)
})
Convey("It should contain the user name", func() {
metas := repo.ComposeMetas()

View File

@@ -22,7 +22,6 @@ import (
"github.com/go-xorm/xorm"
"golang.org/x/crypto/ssh"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting"
@@ -34,10 +33,13 @@ const (
var sshOpLocker sync.Mutex
// KeyType specifies the key type
type KeyType int
const (
// KeyTypeUser specifies the user key
KeyTypeUser = iota + 1
// KeyTypeDeploy specifies the deploy key
KeyTypeDeploy
)
@@ -59,28 +61,31 @@ type PublicKey struct {
HasUsed bool `xorm:"-"`
}
func (k *PublicKey) BeforeInsert() {
k.CreatedUnix = time.Now().Unix()
// BeforeInsert will be invoked by XORM before inserting a record
func (key *PublicKey) BeforeInsert() {
key.CreatedUnix = time.Now().Unix()
}
func (k *PublicKey) BeforeUpdate() {
k.UpdatedUnix = time.Now().Unix()
// BeforeUpdate is invoked from XORM before updating this object.
func (key *PublicKey) BeforeUpdate() {
key.UpdatedUnix = time.Now().Unix()
}
func (k *PublicKey) AfterSet(colName string, _ xorm.Cell) {
// AfterSet is invoked from XORM after setting the value of a field of this object.
func (key *PublicKey) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created_unix":
k.Created = time.Unix(k.CreatedUnix, 0).Local()
key.Created = time.Unix(key.CreatedUnix, 0).Local()
case "updated_unix":
k.Updated = time.Unix(k.UpdatedUnix, 0).Local()
k.HasUsed = k.Updated.After(k.Created)
k.HasRecentActivity = k.Updated.Add(7 * 24 * time.Hour).After(time.Now())
key.Updated = time.Unix(key.UpdatedUnix, 0).Local()
key.HasUsed = key.Updated.After(key.Created)
key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now())
}
}
// OmitEmail returns content of public key without email address.
func (k *PublicKey) OmitEmail() string {
return strings.Join(strings.Split(k.Content, " ")[:2], " ")
func (key *PublicKey) OmitEmail() string {
return strings.Join(strings.Split(key.Content, " ")[:2], " ")
}
// AuthorizedString returns formatted public key string for authorized_keys file.
@@ -106,6 +111,8 @@ func extractTypeFromBase64Key(key string) (string, error) {
func parseKeyString(content string) (string, error) {
// Transform all legal line endings to a single "\n".
content = strings.NewReplacer("\r\n", "\n", "\r", "\n").Replace(content)
// remove trailing newline (and beginning spaces too)
content = strings.TrimSpace(content)
lines := strings.Split(content, "\n")
var keyType, keyContent, keyComment string
@@ -366,7 +373,12 @@ func addKey(e Engine, key *PublicKey) (err error) {
// Calculate fingerprint.
tmpPath := strings.Replace(path.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()),
"id_rsa.pub"), "\\", "/", -1)
os.MkdirAll(path.Dir(tmpPath), os.ModePerm)
dir := path.Dir(tmpPath)
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return fmt.Errorf("Fail to create dir %s: %v", dir, err)
}
if err = ioutil.WriteFile(tmpPath, []byte(key.Content), 0644); err != nil {
return err
}
@@ -476,7 +488,7 @@ func deletePublicKeys(e *xorm.Session, keyIDs ...int64) error {
return nil
}
_, err := e.In("id", strings.Join(base.Int64sToStrings(keyIDs), ",")).Delete(new(PublicKey))
_, err := e.In("id", keyIDs).Delete(new(PublicKey))
return err
}
@@ -572,32 +584,35 @@ type DeployKey struct {
HasUsed bool `xorm:"-"`
}
func (k *DeployKey) BeforeInsert() {
k.CreatedUnix = time.Now().Unix()
// BeforeInsert will be invoked by XORM before inserting a record
func (key *DeployKey) BeforeInsert() {
key.CreatedUnix = time.Now().Unix()
}
func (k *DeployKey) BeforeUpdate() {
k.UpdatedUnix = time.Now().Unix()
// BeforeUpdate is invoked from XORM before updating this object.
func (key *DeployKey) BeforeUpdate() {
key.UpdatedUnix = time.Now().Unix()
}
func (k *DeployKey) AfterSet(colName string, _ xorm.Cell) {
// AfterSet is invoked from XORM after setting the value of a field of this object.
func (key *DeployKey) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created_unix":
k.Created = time.Unix(k.CreatedUnix, 0).Local()
key.Created = time.Unix(key.CreatedUnix, 0).Local()
case "updated_unix":
k.Updated = time.Unix(k.UpdatedUnix, 0).Local()
k.HasUsed = k.Updated.After(k.Created)
k.HasRecentActivity = k.Updated.Add(7 * 24 * time.Hour).After(time.Now())
key.Updated = time.Unix(key.UpdatedUnix, 0).Local()
key.HasUsed = key.Updated.After(key.Created)
key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now())
}
}
// GetContent gets associated public key content.
func (k *DeployKey) GetContent() error {
pkey, err := GetPublicKeyByID(k.KeyID)
func (key *DeployKey) GetContent() error {
pkey, err := GetPublicKeyByID(key.KeyID)
if err != nil {
return err
}
k.Content = pkey.Content
key.Content = pkey.Content
return nil
}

View File

@@ -28,14 +28,17 @@ type AccessToken struct {
HasUsed bool `xorm:"-"`
}
// BeforeInsert will be invoked by XORM before inserting a record representing this object.
func (t *AccessToken) BeforeInsert() {
t.CreatedUnix = time.Now().Unix()
}
// BeforeUpdate is invoked from XORM before updating this object.
func (t *AccessToken) BeforeUpdate() {
t.UpdatedUnix = time.Now().Unix()
}
// AfterSet is invoked from XORM after setting the value of a field of this object.
func (t *AccessToken) AfterSet(colName string, _ xorm.Cell) {
switch colName {
case "created_unix":

View File

@@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/modules/log"
)
// UpdateTask defines an UpdateTask
type UpdateTask struct {
ID int64 `xorm:"pk autoincr"`
UUID string `xorm:"index"`
@@ -23,6 +24,7 @@ type UpdateTask struct {
NewCommitID string
}
// AddUpdateTask adds an UpdateTask
func AddUpdateTask(task *UpdateTask) error {
_, err := x.Insert(task)
return err
@@ -42,6 +44,7 @@ func GetUpdateTaskByUUID(uuid string) (*UpdateTask, error) {
return task, nil
}
// DeleteUpdateTaskByUUID deletes an UpdateTask from the database
func DeleteUpdateTaskByUUID(uuid string) error {
_, err := x.Delete(&UpdateTask{UUID: uuid})
return err
@@ -60,8 +63,9 @@ func CommitToPushCommit(commit *git.Commit) *PushCommit {
}
}
// ListToPushCommits transforms a list.List to PushCommits type.
func ListToPushCommits(l *list.List) *PushCommits {
commits := make([]*PushCommit, 0)
var commits []*PushCommit
var actEmail string
for e := l.Front(); e != nil; e = e.Next() {
commit := e.Value.(*git.Commit)
@@ -73,6 +77,7 @@ func ListToPushCommits(l *list.List) *PushCommits {
return &PushCommits{l.Len(), commits, "", nil}
}
// PushUpdateOptions defines the push update options
type PushUpdateOptions struct {
PusherID int64
PusherName string

Some files were not shown because too many files have changed in this diff Show More