Merge branch 'master' into repo-search-sort
This commit is contained in:
commit
5d21d47973
15
.drone.yml
15
.drone.yml
|
|
@ -4,7 +4,7 @@ workspace:
|
||||||
|
|
||||||
clone:
|
clone:
|
||||||
git:
|
git:
|
||||||
image: plugins/git:1
|
image: plugins/git:next
|
||||||
depth: 50
|
depth: 50
|
||||||
tags: true
|
tags: true
|
||||||
|
|
||||||
|
|
@ -75,6 +75,7 @@ pipeline:
|
||||||
- make lint
|
- make lint
|
||||||
- make fmt-check
|
- make fmt-check
|
||||||
- make swagger-check
|
- make swagger-check
|
||||||
|
- make swagger-validate
|
||||||
- make misspell-check
|
- make misspell-check
|
||||||
- make test-vendor
|
- make test-vendor
|
||||||
- make build
|
- make build
|
||||||
|
|
@ -254,6 +255,18 @@ pipeline:
|
||||||
when:
|
when:
|
||||||
event: [ push, tag ]
|
event: [ push, tag ]
|
||||||
|
|
||||||
|
gpg-sign:
|
||||||
|
image: plugins/gpgsign:1
|
||||||
|
pull: true
|
||||||
|
secrets: [ gpgsign_key, gpgsign_passphrase ]
|
||||||
|
detach_sign: true
|
||||||
|
files:
|
||||||
|
- dist/release/*
|
||||||
|
excludes:
|
||||||
|
- dist/release/*.sha256
|
||||||
|
when:
|
||||||
|
event: [ push, tag ]
|
||||||
|
|
||||||
release:
|
release:
|
||||||
image: plugins/s3:1
|
image: plugins/s3:1
|
||||||
pull: true
|
pull: true
|
||||||
|
|
|
||||||
46
contrib/init/sunos/gitea.xml
Normal file
46
contrib/init/sunos/gitea.xml
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
|
||||||
|
<service_bundle type="manifest" name="export">
|
||||||
|
<service name="gitea" type="service" version="1">
|
||||||
|
<create_default_instance enabled="false"/>
|
||||||
|
|
||||||
|
<dependency name="network" grouping="require_all" restart_on="refresh" type="service">
|
||||||
|
<service_fmri value="svc:/milestone/network:default"/>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency name="filesystem" grouping="require_all" restart_on="refresh" type="service">
|
||||||
|
<service_fmri value="svc:/system/filesystem/local"/>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<exec_method
|
||||||
|
type="method"
|
||||||
|
name="start"
|
||||||
|
exec="/opt/local/bin/gitea web"
|
||||||
|
timeout_seconds="60">
|
||||||
|
<method_context>
|
||||||
|
<method_credential user="git" group="git" />
|
||||||
|
<method_environment>
|
||||||
|
<envvar name='GITEA_WORK_DIR' value='/opt/local/share/gitea'/>
|
||||||
|
<envvar name='GITEA_CUSTOM' value='/opt/local/etc/gitea'/>
|
||||||
|
<envvar name='HOME' value='/var/db/gitea'/>
|
||||||
|
<envvar name='PATH' value='/opt/local/bin:${PATH}'/>
|
||||||
|
<envvar name='USER' value='git'/>
|
||||||
|
</method_environment>
|
||||||
|
</method_context>
|
||||||
|
</exec_method>
|
||||||
|
<exec_method type="method" name="stop" exec=":kill" timeout_seconds="60"/>
|
||||||
|
|
||||||
|
<property_group name="application" type="application"></property_group>
|
||||||
|
<property_group name="startd" type="framework">
|
||||||
|
<propval name="duration" type="astring" value="child"/>
|
||||||
|
<propval name="ignore_error" type="astring" value="core,signal"/>
|
||||||
|
</property_group>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<common_name>
|
||||||
|
<loctext xml:lang="C">A painless, self-hosted Git service</loctext>
|
||||||
|
</common_name>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</service>
|
||||||
|
</service_bundle>
|
||||||
|
|
@ -601,9 +601,9 @@ ko-KR = ko
|
||||||
[U2F]
|
[U2F]
|
||||||
; Two Factor authentication with security keys
|
; Two Factor authentication with security keys
|
||||||
; https://developers.yubico.com/U2F/App_ID.html
|
; https://developers.yubico.com/U2F/App_ID.html
|
||||||
APP_ID = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s
|
APP_ID = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
|
||||||
; Comma seperated list of truisted facets
|
; Comma seperated list of truisted facets
|
||||||
TRUSTED_FACETS = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s
|
TRUSTED_FACETS = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
|
||||||
|
|
||||||
; Extension mapping to highlight class
|
; Extension mapping to highlight class
|
||||||
; e.g. .toml=ini
|
; e.g. .toml=ini
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
/usr/sbin/update-ca-certificates
|
|
||||||
|
|
||||||
if [ ! -d /data/git/.ssh ]; then
|
if [ ! -d /data/git/.ssh ]; then
|
||||||
mkdir -p /data/git/.ssh
|
mkdir -p /data/git/.ssh
|
||||||
chmod 700 /data/git/.ssh
|
chmod 700 /data/git/.ssh
|
||||||
|
|
|
||||||
75
docs/content/doc/advanced/api-usage.en-us.md
Normal file
75
docs/content/doc/advanced/api-usage.en-us.md
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
---
|
||||||
|
date: "2018-06-24:00:00+02:00"
|
||||||
|
title: "API Usage"
|
||||||
|
slug: "api-usage"
|
||||||
|
weight: 40
|
||||||
|
toc: true
|
||||||
|
draft: false
|
||||||
|
menu:
|
||||||
|
sidebar:
|
||||||
|
parent: "advanced"
|
||||||
|
name: "API Usage"
|
||||||
|
weight: 40
|
||||||
|
identifier: "api-usage"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Gitea API Usage
|
||||||
|
|
||||||
|
## Enabling/configuring API access
|
||||||
|
|
||||||
|
By default, `ENABLE_SWAGGER_ENDPOINT` is true, and
|
||||||
|
`MAX_RESPONSE_ITEMS` is set to 50. See [Config Cheat
|
||||||
|
Sheet](https://docs.gitea.io/en-us/config-cheat-sheet/) for more
|
||||||
|
information.
|
||||||
|
|
||||||
|
## Authentication via the API
|
||||||
|
|
||||||
|
Gitea supports these methods of API authentication:
|
||||||
|
|
||||||
|
- HTTP basic authentication
|
||||||
|
- `token=...` parameter in URL query string
|
||||||
|
- `access_token=...` parameter in URL query string
|
||||||
|
- `Authorization: token ...` header in HTTP headers
|
||||||
|
|
||||||
|
All of these methods accept the same apiKey token type. You can
|
||||||
|
better understand this by looking at the code -- as of this writing,
|
||||||
|
Gitea parses queries and headers to find the token in
|
||||||
|
[modules/auth/auth.go](https://github.com/go-gitea/gitea/blob/6efdcaed86565c91a3dc77631372a9cc45a58e89/modules/auth/auth.go#L47).
|
||||||
|
|
||||||
|
You can create an apiKey token via your gitea install's web interface:
|
||||||
|
`Settings | Applications | Generate New Token`.
|
||||||
|
|
||||||
|
### More on the `Authorization:` header
|
||||||
|
|
||||||
|
For historical reasons, Gitea needs the word `token` included before
|
||||||
|
the apiKey token in an authorization header, like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
Authorization: token 65eaa9c8ef52460d22a93307fe0aee76289dc675
|
||||||
|
```
|
||||||
|
|
||||||
|
In a `curl` command, for instance, this would look like:
|
||||||
|
|
||||||
|
```
|
||||||
|
curl -X POST "http://localhost:4000/api/v1/repos/test1/test1/issues" \
|
||||||
|
-H "accept: application/json" \
|
||||||
|
-H "Authorization: token 65eaa9c8ef52460d22a93307fe0aee76289dc675" \
|
||||||
|
-H "Content-Type: application/json" -d "{ \"body\": \"testing\", \"title\": \"test 20\"}" -i
|
||||||
|
```
|
||||||
|
|
||||||
|
As mentioned above, the token used is the same one you would use in
|
||||||
|
the `token=` string in a GET request.
|
||||||
|
|
||||||
|
## Listing your issued tokens via the API
|
||||||
|
|
||||||
|
As mentioned in
|
||||||
|
[#3842](https://github.com/go-gitea/gitea/issues/3842#issuecomment-397743346),
|
||||||
|
`/users/:name/tokens` is special and requires you to authenticate
|
||||||
|
using BasicAuth, as follows:
|
||||||
|
|
||||||
|
### Using basic authentication:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl --request GET --url https://yourusername:yourpassword@gitea.your.host/api/v1/users/yourusername/tokens
|
||||||
|
[{"name":"test","sha1":"..."},{"name":"dev","sha1":"..."}]
|
||||||
|
```
|
||||||
|
|
@ -27,659 +27,93 @@ _Symbols used in table:_
|
||||||
|
|
||||||
* _✘ - unsupported_
|
* _✘ - unsupported_
|
||||||
|
|
||||||
<table border="1" cellpadding="4">
|
#### General Features
|
||||||
<thead>
|
|
||||||
<tr>
|
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||||
<td>Feature</td>
|
|---------|-------|------|-----------|-----------|-----------|-----------|--------------|
|
||||||
<td>Gitea</td>
|
| Open source and free | ✓ | ✓ | ✘| ✓ | ✘ | ✘ | ✓ |
|
||||||
<td>Gogs</td>
|
| Low resource usage (RAM/CPU) | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✘ |
|
||||||
<td>GitHub EE</td>
|
| Multiple database support | ✓ | ✓ | ✘ | ⁄ | ⁄ | ✓ | ✓ |
|
||||||
<td>GitLab CE</td>
|
| Multiple OS support | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ | ✓ |
|
||||||
<td>GitLab EE</td>
|
| Easy upgrade process | ✓ | ✓ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||||
<td>BitBucket</td>
|
| Markdown support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<td>RhodeCode CE</td>
|
| Static Git-powered pages | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
</tr>
|
| Integrated Git-powered wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
</thead>
|
| Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<tbody>
|
| Repository Tokens with write rights | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
|
||||||
<tr>
|
| Built-in Container Registry | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>Open source and free</td>
|
| External git mirroring | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
||||||
<td>✓</td>
|
| FIDO U2F (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
<td>✓</td>
|
| Built-in CI/CD | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>✘</td>
|
| Subgroups: groups within groups | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✓ |
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
#### Code management
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||||
</tr>
|
|---------|-------|------|-----------|-----------|-----------|-----------|--------------|
|
||||||
<tr>
|
| Repository topics | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>Issue tracker</td>
|
| Repository code search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<td>✓</td>
|
| Global code search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<td>✓</td>
|
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ⁄ | ✓ |
|
||||||
<td>✓</td>
|
| Group Milestones | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>✓</td>
|
| Granular user roles (Code, Issues, Wiki etc) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>✓</td>
|
| Verified Committer | ✘ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
|
||||||
<td>✓</td>
|
| GPG Signed Commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<td>✘</td>
|
| Reject unsigned commits | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
|
||||||
</tr>
|
| Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<tr>
|
| Branch manager | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<td>Pull/Merge requests</td>
|
| Create new branches | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>✓</td>
|
| Web code editor | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<td>✓</td>
|
| Commit graph | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
#### Issue Tracker
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||||
<td>✓</td>
|
|---------|-------|------|-----------|-----------|-----------|-----------|--------------|
|
||||||
</tr>
|
| Issue tracker | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
<tr>
|
| Issue templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>Squash merging</td>
|
| Labels | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>✓</td>
|
| Time tracking | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>✘</td>
|
| Multiple assignees for issues | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>✓</td>
|
| Related issues | ✘ | ✘ | ⁄ | ✘ | ✓ | ✘ | ✘ |
|
||||||
<td>✘</td>
|
| Confidential issues | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>✓</td>
|
| Comment reactions | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>✓</td>
|
| Lock Discussion | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>✓</td>
|
| Batch issue handling | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
</tr>
|
| Issue Boards | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<tr>
|
| Create new branches from issues | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>Rebase merging</td>
|
| Issue search | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
<td>✓</td>
|
| Global issue search | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
#### Pull/Merge requests
|
||||||
<td>✘</td>
|
|
||||||
<td>⁄</td>
|
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||||
<td>✘</td>
|
|---------|-------|------|-----------|-----------|-----------|-----------|--------------|
|
||||||
<td>✓</td>
|
| Pull/Merge requests | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
</tr>
|
| Squash merging | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✓ |
|
||||||
<tr>
|
| Rebase merging | ✓ | ✓ | ✓ | ✘ | ⁄ | ✘ | ✓ |
|
||||||
<td>Pull/Merge request inline comments</td>
|
| Pull/Merge request inline comments | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<td>✘</td>
|
| Pull/Merge request approval | ✘ | ✘ | ⁄ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<td>✘</td>
|
| Merge conflict resolution | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
<td>✓</td>
|
| Restrict push and merge access to certain users | ✓ | ✘ | ✓ | ⁄ | ✓ | ✓ | ✓ |
|
||||||
<td>✓</td>
|
| Revert specific commits or a merge request | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
<td>✓</td>
|
| Pull/Merge requests templates | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>✓</td>
|
| Cherry-picking changes | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
#### 3rd-party integrations
|
||||||
<td>Pull/Merge request approval</td>
|
|
||||||
<td>✘</td>
|
| Feature | Gitea | Gogs | GitHub EE | GitLab CE | GitLab EE | BitBucket | RhodeCode CE |
|
||||||
<td>✘</td>
|
|---------|-------|------|-----------|-----------|-----------|-----------|--------------|
|
||||||
<td>⁄</td>
|
| Webhook support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<td>✓</td>
|
| Custom Git Hooks | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<td>✓</td>
|
| AD / LDAP integration | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<td>✓</td>
|
| Multiple LDAP / AD server support | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
||||||
<td>✓</td>
|
| LDAP user synchronization | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
</tr>
|
| OpenId Connect support | ✓ | ✘ | ✓ | ✓ | ✓ | ? | ✘ |
|
||||||
<tr>
|
| OAuth 2.0 integration (external authorization) | ✓ | ✘ | ⁄ | ✓ | ✓ | ? | ✓ |
|
||||||
<td>Merge conflict resolution</td>
|
| Act as OAuth 2.0 provider | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
<td>✘</td>
|
| Two factor authentication (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||||
<td>✘</td>
|
| Mattermost/Slack integration | ✓ | ✓ | ⁄ | ✓ | ✓ | ⁄ | ✓ |
|
||||||
<td>✓</td>
|
| Discord integration | ✓ | ✓ | ✓ | ✘ | ✘ | ✘ | ✘ |
|
||||||
<td>✓</td>
|
| External CI/CD status display | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Restrict push and merge access to certain users</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>⁄</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Markdown support</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Issues and pull/merge requests templates</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Revert specific commits or a merge request</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Labels</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Time tracking</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Multiple assignees for issues</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Related issues</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>⁄</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Confidential issues</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Comment reactions</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Lock Discussion</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Batch issue handling</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Issue Boards</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Create new branches from issues</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Commit graph</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Web code editor</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Branch manager</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Create new branches</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Repository topics</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Repository code search</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Global code search</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Issue search</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Global issue search</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Git LFS 2.0</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>⁄</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Integrated Git-powered wiki</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Static Git-powered pages</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Group Milestones</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Granular user roles (Code, Issues, Wiki etc)</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Cherry-picking changes</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>GPG Signed Commits</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Reject unsigned commits</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Verified Committer</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>?</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Subgroups: groups within groups</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Custom Git Hooks</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Repository Activity page</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Deploy Tokens</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Repository Tokens with write rights</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Easy upgrade process</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Built-in Container Registry</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>External git mirroring</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>AD / LDAP integration</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Multiple LDAP / AD server support</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>LDAP user synchronization</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>OpenId Connect support</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>?</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>OAuth 2.0 integration (external authorization)</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>⁄</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>?</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Act as OAuth 2.0 provider</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Two factor authentication (2FA)</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>FIDO U2F (2FA)</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Webhook support</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Mattermost/Slack integration</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>⁄</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>⁄</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Discord integration</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Built-in CI/CD</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>External CI/CD status display</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Multiple database support</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>⁄</td>
|
|
||||||
<td>⁄</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Multiple OS support</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✓</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Low resource usage (RAM/CPU)</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✓</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
<td>✘</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
|
||||||
|
|
@ -245,6 +245,8 @@ You can configure some of Gitea's settings via environment variables:
|
||||||
* `SECRET_KEY`: **""**: Global secret key. This should be changed. If this has a value and `INSTALL_LOCK` is empty, `INSTALL_LOCK` will automatically set to `true`.
|
* `SECRET_KEY`: **""**: Global secret key. This should be changed. If this has a value and `INSTALL_LOCK` is empty, `INSTALL_LOCK` will automatically set to `true`.
|
||||||
* `DISABLE_REGISTRATION`: **false**: Disable registration, after which only admin can create accounts for users.
|
* `DISABLE_REGISTRATION`: **false**: Disable registration, after which only admin can create accounts for users.
|
||||||
* `REQUIRE_SIGNIN_VIEW`: **false**: Enable this to force users to log in to view any page.
|
* `REQUIRE_SIGNIN_VIEW`: **false**: Enable this to force users to log in to view any page.
|
||||||
|
* `USER_UID`: **1000**: The UID (Unix user ID) of the user that runs Gitea within the container. Match this to the UID of the owner of the `/data` volume if using host volumes (this is not necessary with named volumes).
|
||||||
|
* `USER_GID`: **1000**: The GID (Unix group ID) of the user that runs Gitea within the container. Match this to the GID of the owner of the `/data` volume if using host volumes (this is not necessary with named volumes).
|
||||||
|
|
||||||
# Customization
|
# Customization
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ Make sure to perform a clean build before running tests:
|
||||||
|
|
||||||
## Run all tests via local drone
|
## Run all tests via local drone
|
||||||
```
|
```
|
||||||
drone exec --local --build.event "pull_request"
|
drone exec --local --build-event "pull_request"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Run sqlite integrations tests
|
## Run sqlite integrations tests
|
||||||
|
|
|
||||||
|
|
@ -67,9 +67,9 @@ func TestAPISearchRepo(t *testing.T) {
|
||||||
expectedResults
|
expectedResults
|
||||||
}{
|
}{
|
||||||
{name: "RepositoriesMax50", requestURL: "/api/v1/repos/search?limit=50", expectedResults: expectedResults{
|
{name: "RepositoriesMax50", requestURL: "/api/v1/repos/search?limit=50", expectedResults: expectedResults{
|
||||||
nil: {count: 15},
|
nil: {count: 16},
|
||||||
user: {count: 15},
|
user: {count: 16},
|
||||||
user2: {count: 15}},
|
user2: {count: 16}},
|
||||||
},
|
},
|
||||||
{name: "RepositoriesMax10", requestURL: "/api/v1/repos/search?limit=10", expectedResults: expectedResults{
|
{name: "RepositoriesMax10", requestURL: "/api/v1/repos/search?limit=10", expectedResults: expectedResults{
|
||||||
nil: {count: 10},
|
nil: {count: 10},
|
||||||
|
|
|
||||||
|
|
@ -68,3 +68,25 @@ func TestSettingShowUserEmailProfile(t *testing.T) {
|
||||||
|
|
||||||
setting.UI.ShowUserEmail = showUserEmail
|
setting.UI.ShowUserEmail = showUserEmail
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSettingLandingPage(t *testing.T) {
|
||||||
|
prepareTestEnv(t)
|
||||||
|
|
||||||
|
landingPage := setting.LandingPageURL
|
||||||
|
|
||||||
|
setting.LandingPageURL = setting.LandingPageHome
|
||||||
|
req := NewRequest(t, "GET", "/")
|
||||||
|
MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
setting.LandingPageURL = setting.LandingPageExplore
|
||||||
|
req = NewRequest(t, "GET", "/")
|
||||||
|
resp := MakeRequest(t, req, http.StatusFound)
|
||||||
|
assert.Equal(t, "/explore", resp.Header().Get("Location"))
|
||||||
|
|
||||||
|
setting.LandingPageURL = setting.LandingPageOrganizations
|
||||||
|
req = NewRequest(t, "GET", "/")
|
||||||
|
resp = MakeRequest(t, req, http.StatusFound)
|
||||||
|
assert.Equal(t, "/explore/organizations", resp.Header().Get("Location"))
|
||||||
|
|
||||||
|
setting.LandingPageURL = landingPage
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,12 @@ func TestAccessLevel(t *testing.T) {
|
||||||
|
|
||||||
user1 := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
user1 := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
||||||
user2 := AssertExistsAndLoadBean(t, &User{ID: 5}).(*User)
|
user2 := AssertExistsAndLoadBean(t, &User{ID: 5}).(*User)
|
||||||
repo1 := AssertExistsAndLoadBean(t, &Repository{OwnerID: 2, IsPrivate: false}).(*Repository)
|
// A public repository owned by User 2
|
||||||
repo2 := AssertExistsAndLoadBean(t, &Repository{OwnerID: 3, IsPrivate: true}).(*Repository)
|
repo1 := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
|
||||||
|
assert.False(t, repo1.IsPrivate)
|
||||||
|
// A private repository owned by Org 3
|
||||||
|
repo2 := AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository)
|
||||||
|
assert.True(t, repo2.IsPrivate)
|
||||||
|
|
||||||
level, err := AccessLevel(user1.ID, repo1)
|
level, err := AccessLevel(user1.ID, repo1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
@ -47,8 +51,12 @@ func TestHasAccess(t *testing.T) {
|
||||||
|
|
||||||
user1 := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
user1 := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
||||||
user2 := AssertExistsAndLoadBean(t, &User{ID: 5}).(*User)
|
user2 := AssertExistsAndLoadBean(t, &User{ID: 5}).(*User)
|
||||||
repo1 := AssertExistsAndLoadBean(t, &Repository{OwnerID: 2, IsPrivate: false}).(*Repository)
|
// A public repository owned by User 2
|
||||||
repo2 := AssertExistsAndLoadBean(t, &Repository{OwnerID: 3, IsPrivate: true}).(*Repository)
|
repo1 := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
|
||||||
|
assert.False(t, repo1.IsPrivate)
|
||||||
|
// A private repository owned by Org 3
|
||||||
|
repo2 := AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository)
|
||||||
|
assert.True(t, repo2.IsPrivate)
|
||||||
|
|
||||||
for _, accessMode := range accessModes {
|
for _, accessMode := range accessModes {
|
||||||
has, err := HasAccess(user1.ID, repo1, accessMode)
|
has, err := HasAccess(user1.ID, repo1, accessMode)
|
||||||
|
|
|
||||||
|
|
@ -351,7 +351,7 @@
|
||||||
is_mirror: true
|
is_mirror: true
|
||||||
num_forks: 1
|
num_forks: 1
|
||||||
is_fork: false
|
is_fork: false
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 29
|
id: 29
|
||||||
fork_id: 27
|
fork_id: 27
|
||||||
|
|
@ -365,7 +365,7 @@
|
||||||
num_closed_pulls: 0
|
num_closed_pulls: 0
|
||||||
is_mirror: false
|
is_mirror: false
|
||||||
is_fork: true
|
is_fork: true
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 30
|
id: 30
|
||||||
fork_id: 28
|
fork_id: 28
|
||||||
|
|
@ -389,3 +389,14 @@
|
||||||
num_forks: 0
|
num_forks: 0
|
||||||
num_issues: 0
|
num_issues: 0
|
||||||
is_mirror: false
|
is_mirror: false
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 32
|
||||||
|
owner_id: 3
|
||||||
|
lower_name: repo21
|
||||||
|
name: repo21
|
||||||
|
is_private: false
|
||||||
|
num_stars: 0
|
||||||
|
num_forks: 0
|
||||||
|
num_issues: 0
|
||||||
|
is_mirror: false
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,8 @@
|
||||||
lower_name: owners
|
lower_name: owners
|
||||||
name: Owners
|
name: Owners
|
||||||
authorize: 4 # owner
|
authorize: 4 # owner
|
||||||
num_repos: 2
|
num_repos: 3
|
||||||
num_members: 1
|
num_members: 1
|
||||||
unit_types: '[1,2,3,4,5,6,7]'
|
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 2
|
id: 2
|
||||||
|
|
@ -16,7 +15,6 @@
|
||||||
authorize: 2 # write
|
authorize: 2 # write
|
||||||
num_repos: 1
|
num_repos: 1
|
||||||
num_members: 2
|
num_members: 2
|
||||||
unit_types: '[1,2,3,4,5,6,7]'
|
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 3
|
id: 3
|
||||||
|
|
@ -26,7 +24,6 @@
|
||||||
authorize: 4 # owner
|
authorize: 4 # owner
|
||||||
num_repos: 0
|
num_repos: 0
|
||||||
num_members: 1
|
num_members: 1
|
||||||
unit_types: '[1,2,3,4,5,6,7]'
|
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 4
|
id: 4
|
||||||
|
|
@ -36,7 +33,6 @@
|
||||||
authorize: 4 # owner
|
authorize: 4 # owner
|
||||||
num_repos: 0
|
num_repos: 0
|
||||||
num_members: 1
|
num_members: 1
|
||||||
unit_types: '[1,2,3,4,5,6,7]'
|
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 5
|
id: 5
|
||||||
|
|
@ -46,7 +42,6 @@
|
||||||
authorize: 4 # owner
|
authorize: 4 # owner
|
||||||
num_repos: 2
|
num_repos: 2
|
||||||
num_members: 2
|
num_members: 2
|
||||||
unit_types: '[1,2,3,4,5,6,7]'
|
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 6
|
id: 6
|
||||||
|
|
@ -56,4 +51,3 @@
|
||||||
authorize: 4 # owner
|
authorize: 4 # owner
|
||||||
num_repos: 2
|
num_repos: 2
|
||||||
num_members: 1
|
num_members: 1
|
||||||
unit_types: '[1,2,3,4,5,6,7]'
|
|
||||||
|
|
@ -33,9 +33,15 @@
|
||||||
org_id: 19
|
org_id: 19
|
||||||
team_id: 6
|
team_id: 6
|
||||||
repo_id: 27
|
repo_id: 27
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 7
|
id: 7
|
||||||
org_id: 19
|
org_id: 19
|
||||||
team_id: 6
|
team_id: 6
|
||||||
repo_id: 28
|
repo_id: 28
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 8
|
||||||
|
org_id: 3
|
||||||
|
team_id: 1
|
||||||
|
repo_id: 32
|
||||||
|
|
|
||||||
209
models/fixtures/team_unit.yml
Normal file
209
models/fixtures/team_unit.yml
Normal file
|
|
@ -0,0 +1,209 @@
|
||||||
|
-
|
||||||
|
id: 1
|
||||||
|
team_id: 1
|
||||||
|
type: 1
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 2
|
||||||
|
team_id: 1
|
||||||
|
type: 2
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 3
|
||||||
|
team_id: 1
|
||||||
|
type: 3
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 4
|
||||||
|
team_id: 1
|
||||||
|
type: 4
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 5
|
||||||
|
team_id: 1
|
||||||
|
type: 5
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 6
|
||||||
|
team_id: 1
|
||||||
|
type: 6
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 7
|
||||||
|
team_id: 1
|
||||||
|
type: 7
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 8
|
||||||
|
team_id: 2
|
||||||
|
type: 1
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 9
|
||||||
|
team_id: 2
|
||||||
|
type: 2
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 10
|
||||||
|
team_id: 2
|
||||||
|
type: 3
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 11
|
||||||
|
team_id: 2
|
||||||
|
type: 4
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 12
|
||||||
|
team_id: 2
|
||||||
|
type: 5
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 13
|
||||||
|
team_id: 2
|
||||||
|
type: 6
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 14
|
||||||
|
team_id: 2
|
||||||
|
type: 7
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 15
|
||||||
|
team_id: 3
|
||||||
|
type: 1
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 16
|
||||||
|
team_id: 3
|
||||||
|
type: 2
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 17
|
||||||
|
team_id: 3
|
||||||
|
type: 3
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 18
|
||||||
|
team_id: 3
|
||||||
|
type: 4
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 19
|
||||||
|
team_id: 3
|
||||||
|
type: 5
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 20
|
||||||
|
team_id: 3
|
||||||
|
type: 6
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 21
|
||||||
|
team_id: 3
|
||||||
|
type: 7
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 22
|
||||||
|
team_id: 4
|
||||||
|
type: 1
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 23
|
||||||
|
team_id: 4
|
||||||
|
type: 2
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 24
|
||||||
|
team_id: 4
|
||||||
|
type: 3
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 25
|
||||||
|
team_id: 4
|
||||||
|
type: 4
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 26
|
||||||
|
team_id: 4
|
||||||
|
type: 5
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 27
|
||||||
|
team_id: 4
|
||||||
|
type: 6
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 28
|
||||||
|
team_id: 4
|
||||||
|
type: 7
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 29
|
||||||
|
team_id: 5
|
||||||
|
type: 1
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 30
|
||||||
|
team_id: 5
|
||||||
|
type: 2
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 31
|
||||||
|
team_id: 5
|
||||||
|
type: 3
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 32
|
||||||
|
team_id: 5
|
||||||
|
type: 4
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 33
|
||||||
|
team_id: 5
|
||||||
|
type: 5
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 34
|
||||||
|
team_id: 5
|
||||||
|
type: 6
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 35
|
||||||
|
team_id: 5
|
||||||
|
type: 7
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 36
|
||||||
|
team_id: 6
|
||||||
|
type: 1
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 37
|
||||||
|
team_id: 6
|
||||||
|
type: 2
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 38
|
||||||
|
team_id: 6
|
||||||
|
type: 3
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 39
|
||||||
|
team_id: 6
|
||||||
|
type: 4
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 40
|
||||||
|
team_id: 6
|
||||||
|
type: 5
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 41
|
||||||
|
team_id: 6
|
||||||
|
type: 6
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 42
|
||||||
|
team_id: 6
|
||||||
|
type: 7
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
is_admin: false
|
is_admin: false
|
||||||
avatar: avatar3
|
avatar: avatar3
|
||||||
avatar_email: user3@example.com
|
avatar_email: user3@example.com
|
||||||
num_repos: 2
|
num_repos: 3
|
||||||
num_members: 2
|
num_members: 2
|
||||||
num_teams: 2
|
num_teams: 2
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,10 @@ func (c *Comment) AfterLoad(session *xorm.Session) {
|
||||||
|
|
||||||
// AfterDelete is invoked from XORM after the object is deleted.
|
// AfterDelete is invoked from XORM after the object is deleted.
|
||||||
func (c *Comment) AfterDelete() {
|
func (c *Comment) AfterDelete() {
|
||||||
|
if c.ID <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
_, err := DeleteAttachmentsByComment(c.ID, true)
|
_, err := DeleteAttachmentsByComment(c.ID, true)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -71,3 +71,15 @@ func getIssueWatchers(e Engine, issueID int64) (watches []*IssueWatch, err error
|
||||||
Find(&watches)
|
Find(&watches)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func removeIssueWatchersByRepoID(e Engine, userID int64, repoID int64) error {
|
||||||
|
iw := &IssueWatch{
|
||||||
|
IsWatching: false,
|
||||||
|
}
|
||||||
|
_, err := e.
|
||||||
|
Join("INNER", "issue", "`issue`.id = `issue_watch`.issue_id AND `issue`.repo_id = ?", repoID).
|
||||||
|
Cols("is_watching", "updated_unix").
|
||||||
|
Where("`issue_watch`.user_id = ?", userID).
|
||||||
|
Update(iw)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,12 @@ var migrations = []Migration{
|
||||||
NewMigration("add u2f", addU2FReg),
|
NewMigration("add u2f", addU2FReg),
|
||||||
// v66 -> v67
|
// v66 -> v67
|
||||||
NewMigration("add login source id column for public_key table", addLoginSourceIDToPublicKeyTable),
|
NewMigration("add login source id column for public_key table", addLoginSourceIDToPublicKeyTable),
|
||||||
|
// v67 -> v68
|
||||||
|
NewMigration("remove stale watches", removeStaleWatches),
|
||||||
|
// v68 -> V69
|
||||||
|
NewMigration("Reformat and remove incorrect topics", reformatAndRemoveIncorrectTopics),
|
||||||
|
// v69 -> v70
|
||||||
|
NewMigration("move team units to team_unit table", moveTeamUnitsToTeamUnitTable),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate database to current version
|
// Migrate database to current version
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,15 @@ func removeCommitsUnitType(x *xorm.Engine) (err error) {
|
||||||
Created time.Time `xorm:"-"`
|
Created time.Time `xorm:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Team struct {
|
||||||
|
ID int64
|
||||||
|
UnitTypes []int `xorm:"json"`
|
||||||
|
}
|
||||||
|
|
||||||
// Update team unit types
|
// Update team unit types
|
||||||
const batchSize = 100
|
const batchSize = 100
|
||||||
for start := 0; ; start += batchSize {
|
for start := 0; ; start += batchSize {
|
||||||
teams := make([]*models.Team, 0, batchSize)
|
teams := make([]*Team, 0, batchSize)
|
||||||
if err := x.Limit(batchSize, start).Find(&teams); err != nil {
|
if err := x.Limit(batchSize, start).Find(&teams); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -36,7 +41,7 @@ func removeCommitsUnitType(x *xorm.Engine) (err error) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
for _, team := range teams {
|
for _, team := range teams {
|
||||||
ut := make([]models.UnitType, 0, len(team.UnitTypes))
|
ut := make([]int, 0, len(team.UnitTypes))
|
||||||
for _, u := range team.UnitTypes {
|
for _, u := range team.UnitTypes {
|
||||||
if u < V16UnitTypeCommits {
|
if u < V16UnitTypeCommits {
|
||||||
ut = append(ut, u)
|
ut = append(ut, u)
|
||||||
|
|
|
||||||
158
models/migrations/v67.go
Normal file
158
models/migrations/v67.go
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
|
"github.com/go-xorm/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func removeStaleWatches(x *xorm.Engine) error {
|
||||||
|
type Watch struct {
|
||||||
|
ID int64
|
||||||
|
UserID int64
|
||||||
|
RepoID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type IssueWatch struct {
|
||||||
|
ID int64
|
||||||
|
UserID int64
|
||||||
|
RepoID int64
|
||||||
|
IsWatching bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type Repository struct {
|
||||||
|
ID int64
|
||||||
|
IsPrivate bool
|
||||||
|
OwnerID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type Access struct {
|
||||||
|
UserID int64
|
||||||
|
RepoID int64
|
||||||
|
Mode int
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// AccessModeNone no access
|
||||||
|
AccessModeNone int = iota // 0
|
||||||
|
// AccessModeRead read access
|
||||||
|
AccessModeRead // 1
|
||||||
|
)
|
||||||
|
|
||||||
|
accessLevel := func(userID int64, repo *Repository) (int, error) {
|
||||||
|
mode := AccessModeNone
|
||||||
|
if !repo.IsPrivate {
|
||||||
|
mode = AccessModeRead
|
||||||
|
}
|
||||||
|
|
||||||
|
if userID == 0 {
|
||||||
|
return mode, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if userID == repo.OwnerID {
|
||||||
|
return 4, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
a := &Access{UserID: userID, RepoID: repo.ID}
|
||||||
|
if has, err := x.Get(a); !has || err != nil {
|
||||||
|
return mode, err
|
||||||
|
}
|
||||||
|
return a.Mode, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
sess := x.NewSession()
|
||||||
|
defer sess.Close()
|
||||||
|
if err := sess.Begin(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
repoCache := make(map[int64]*Repository)
|
||||||
|
err := x.BufferSize(setting.IterateBufferSize).Iterate(new(Watch),
|
||||||
|
func(idx int, bean interface{}) error {
|
||||||
|
watch := bean.(*Watch)
|
||||||
|
|
||||||
|
repo := repoCache[watch.RepoID]
|
||||||
|
if repo == nil {
|
||||||
|
repo = &Repository{
|
||||||
|
ID: watch.RepoID,
|
||||||
|
}
|
||||||
|
if _, err := x.Get(repo); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
repoCache[watch.RepoID] = repo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove watches from now unaccessible repositories
|
||||||
|
mode, err := accessLevel(watch.UserID, repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
has := AccessModeRead <= mode
|
||||||
|
if has {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = sess.Delete(&Watch{0, watch.UserID, repo.ID}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = sess.Exec("UPDATE `repository` SET num_watches = num_watches - 1 WHERE id = ?", repo.ID)
|
||||||
|
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
repoCache = make(map[int64]*Repository)
|
||||||
|
err = x.BufferSize(setting.IterateBufferSize).
|
||||||
|
Distinct("issue_watch.user_id", "issue.repo_id").
|
||||||
|
Join("INNER", "issue", "issue_watch.issue_id = issue.id").
|
||||||
|
Where("issue_watch.is_watching = ?", true).
|
||||||
|
Iterate(new(IssueWatch),
|
||||||
|
func(idx int, bean interface{}) error {
|
||||||
|
watch := bean.(*IssueWatch)
|
||||||
|
|
||||||
|
repo := repoCache[watch.RepoID]
|
||||||
|
if repo == nil {
|
||||||
|
repo = &Repository{
|
||||||
|
ID: watch.RepoID,
|
||||||
|
}
|
||||||
|
if _, err := x.Get(repo); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
repoCache[watch.RepoID] = repo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove issue watches from now unaccssible repositories
|
||||||
|
mode, err := accessLevel(watch.UserID, repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
has := AccessModeRead <= mode
|
||||||
|
if has {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
iw := &IssueWatch{
|
||||||
|
IsWatching: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = sess.
|
||||||
|
Join("INNER", "issue", "`issue`.id = `issue_watch`.issue_id AND `issue`.repo_id = ?", watch.RepoID).
|
||||||
|
Cols("is_watching", "updated_unix").
|
||||||
|
Where("`issue_watch`.user_id = ?", watch.UserID).
|
||||||
|
Update(iw)
|
||||||
|
|
||||||
|
return err
|
||||||
|
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sess.Commit()
|
||||||
|
}
|
||||||
160
models/migrations/v68.go
Normal file
160
models/migrations/v68.go
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
|
||||||
|
"github.com/go-xorm/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func reformatAndRemoveIncorrectTopics(x *xorm.Engine) (err error) {
|
||||||
|
log.Info("This migration could take up to minutes, please be patient.")
|
||||||
|
type Topic struct {
|
||||||
|
ID int64
|
||||||
|
Name string `xorm:"unique"`
|
||||||
|
}
|
||||||
|
|
||||||
|
sess := x.NewSession()
|
||||||
|
defer sess.Close()
|
||||||
|
|
||||||
|
const batchSize = 100
|
||||||
|
touchedRepo := make(map[int64]struct{})
|
||||||
|
topics := make([]*Topic, 0, batchSize)
|
||||||
|
delTopicIDs := make([]int64, 0, batchSize)
|
||||||
|
ids := make([]int64, 0, 30)
|
||||||
|
|
||||||
|
if err := sess.Begin(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Info("Validating existed topics...")
|
||||||
|
for start := 0; ; start += batchSize {
|
||||||
|
topics = topics[:0]
|
||||||
|
if err := sess.Asc("id").Limit(batchSize, start).Find(&topics); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(topics) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for _, topic := range topics {
|
||||||
|
if models.ValidateTopic(topic.Name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
topic.Name = strings.Replace(strings.TrimSpace(strings.ToLower(topic.Name)), " ", "-", -1)
|
||||||
|
|
||||||
|
if err := sess.Table("repo_topic").Cols("repo_id").
|
||||||
|
Where("topic_id = ?", topic.ID).Find(&ids); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, id := range ids {
|
||||||
|
touchedRepo[id] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if models.ValidateTopic(topic.Name) {
|
||||||
|
log.Info("Updating topic: id = %v, name = %v", topic.ID, topic.Name)
|
||||||
|
if _, err := sess.Table("topic").ID(topic.ID).
|
||||||
|
Update(&Topic{Name: topic.Name}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
delTopicIDs = append(delTopicIDs, topic.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Deleting incorrect topics...")
|
||||||
|
for start := 0; ; start += batchSize {
|
||||||
|
if (start + batchSize) < len(delTopicIDs) {
|
||||||
|
ids = delTopicIDs[start:(start + batchSize)]
|
||||||
|
} else {
|
||||||
|
ids = delTopicIDs[start:]
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Deleting 'repo_topic' rows for topics with ids = %v", ids)
|
||||||
|
if _, err := sess.In("topic_id", ids).Delete(&models.RepoTopic{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Deleting topics with id = %v", ids)
|
||||||
|
if _, err := sess.In("id", ids).Delete(&Topic{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ids) < batchSize {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repoTopics := make([]*models.RepoTopic, 0, batchSize)
|
||||||
|
delRepoTopics := make([]*models.RepoTopic, 0, batchSize)
|
||||||
|
tmpRepoTopics := make([]*models.RepoTopic, 0, 30)
|
||||||
|
|
||||||
|
log.Info("Checking the number of topics in the repositories...")
|
||||||
|
for start := 0; ; start += batchSize {
|
||||||
|
repoTopics = repoTopics[:0]
|
||||||
|
if err := sess.Cols("repo_id").Asc("repo_id").Limit(batchSize, start).
|
||||||
|
GroupBy("repo_id").Having("COUNT(*) > 25").Find(&repoTopics); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(repoTopics) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Number of repositories with more than 25 topics: %v", len(repoTopics))
|
||||||
|
for _, repoTopic := range repoTopics {
|
||||||
|
touchedRepo[repoTopic.RepoID] = struct{}{}
|
||||||
|
|
||||||
|
tmpRepoTopics = tmpRepoTopics[:0]
|
||||||
|
if err := sess.Where("repo_id = ?", repoTopic.RepoID).Find(&tmpRepoTopics); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Repository with id = %v has %v topics", repoTopic.RepoID, len(tmpRepoTopics))
|
||||||
|
|
||||||
|
for i := len(tmpRepoTopics) - 1; i > 24; i-- {
|
||||||
|
delRepoTopics = append(delRepoTopics, tmpRepoTopics[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Deleting superfluous topics for repositories (more than 25 topics)...")
|
||||||
|
for _, repoTopic := range delRepoTopics {
|
||||||
|
log.Info("Deleting 'repo_topic' rows for 'repository' with id = %v. Topic id = %v",
|
||||||
|
repoTopic.RepoID, repoTopic.TopicID)
|
||||||
|
|
||||||
|
if _, err := sess.Where("repo_id = ? AND topic_id = ?", repoTopic.RepoID,
|
||||||
|
repoTopic.TopicID).Delete(&models.RepoTopic{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := sess.Exec(
|
||||||
|
"UPDATE topic SET repo_count = (SELECT repo_count FROM topic WHERE id = ?) - 1 WHERE id = ?",
|
||||||
|
repoTopic.TopicID, repoTopic.TopicID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
topicNames := make([]string, 0, 30)
|
||||||
|
log.Info("Updating repositories 'topics' fields...")
|
||||||
|
for repoID := range touchedRepo {
|
||||||
|
if err := sess.Table("topic").Cols("name").
|
||||||
|
Join("INNER", "repo_topic", "topic.id = repo_topic.topic_id").
|
||||||
|
Where("repo_topic.repo_id = ?", repoID).Find(&topicNames); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Info("Updating 'topics' field for repository with id = %v", repoID)
|
||||||
|
if _, err := sess.ID(repoID).Cols("topics").
|
||||||
|
Update(&models.Repository{Topics: topicNames}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := sess.Commit(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
80
models/migrations/v69.go
Normal file
80
models/migrations/v69.go
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/go-xorm/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func moveTeamUnitsToTeamUnitTable(x *xorm.Engine) error {
|
||||||
|
// Team see models/team.go
|
||||||
|
type Team struct {
|
||||||
|
ID int64
|
||||||
|
OrgID int64
|
||||||
|
UnitTypes []int `xorm:"json"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TeamUnit see models/org_team.go
|
||||||
|
type TeamUnit struct {
|
||||||
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
OrgID int64 `xorm:"INDEX"`
|
||||||
|
TeamID int64 `xorm:"UNIQUE(s)"`
|
||||||
|
Type int `xorm:"UNIQUE(s)"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := x.Sync2(new(TeamUnit)); err != nil {
|
||||||
|
return fmt.Errorf("Sync2: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sess := x.NewSession()
|
||||||
|
defer sess.Close()
|
||||||
|
|
||||||
|
if err := sess.Begin(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update team unit types
|
||||||
|
const batchSize = 100
|
||||||
|
for start := 0; ; start += batchSize {
|
||||||
|
teams := make([]*Team, 0, batchSize)
|
||||||
|
if err := x.Limit(batchSize, start).Find(&teams); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(teams) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, team := range teams {
|
||||||
|
var unitTypes []int
|
||||||
|
if len(team.UnitTypes) == 0 {
|
||||||
|
unitTypes = allUnitTypes
|
||||||
|
} else {
|
||||||
|
unitTypes = team.UnitTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert units for team
|
||||||
|
var units = make([]TeamUnit, 0, len(unitTypes))
|
||||||
|
for _, tp := range unitTypes {
|
||||||
|
units = append(units, TeamUnit{
|
||||||
|
OrgID: team.OrgID,
|
||||||
|
TeamID: team.ID,
|
||||||
|
Type: tp,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := sess.Insert(&units); err != nil {
|
||||||
|
return fmt.Errorf("Insert team units: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dropTableColumns(sess, "team", "unit_types"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return sess.Commit()
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
@ -121,6 +122,7 @@ func init() {
|
||||||
new(Reaction),
|
new(Reaction),
|
||||||
new(IssueAssignees),
|
new(IssueAssignees),
|
||||||
new(U2FRegistration),
|
new(U2FRegistration),
|
||||||
|
new(TeamUnit),
|
||||||
)
|
)
|
||||||
|
|
||||||
gonicNames := []string{"SSL", "UID"}
|
gonicNames := []string{"SSL", "UID"}
|
||||||
|
|
@ -184,6 +186,18 @@ func parsePostgreSQLHostPort(info string) (string, string) {
|
||||||
return host, port
|
return host, port
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getPostgreSQLConnectionString(DBHost, DBUser, DBPasswd, DBName, DBParam, DBSSLMode string) (connStr string) {
|
||||||
|
host, port := parsePostgreSQLHostPort(DBHost)
|
||||||
|
if host[0] == '/' { // looks like a unix socket
|
||||||
|
connStr = fmt.Sprintf("postgres://%s:%s@:%s/%s%ssslmode=%s&host=%s",
|
||||||
|
url.PathEscape(DBUser), url.PathEscape(DBPasswd), port, DBName, DBParam, DBSSLMode, host)
|
||||||
|
} else {
|
||||||
|
connStr = fmt.Sprintf("postgres://%s:%s@%s:%s/%s%ssslmode=%s",
|
||||||
|
url.PathEscape(DBUser), url.PathEscape(DBPasswd), host, port, DBName, DBParam, DBSSLMode)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func parseMSSQLHostPort(info string) (string, string) {
|
func parseMSSQLHostPort(info string) (string, string) {
|
||||||
host, port := "127.0.0.1", "1433"
|
host, port := "127.0.0.1", "1433"
|
||||||
if strings.Contains(info, ":") {
|
if strings.Contains(info, ":") {
|
||||||
|
|
@ -214,14 +228,7 @@ func getEngine() (*xorm.Engine, error) {
|
||||||
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name, Param)
|
DbCfg.User, DbCfg.Passwd, DbCfg.Host, DbCfg.Name, Param)
|
||||||
}
|
}
|
||||||
case "postgres":
|
case "postgres":
|
||||||
host, port := parsePostgreSQLHostPort(DbCfg.Host)
|
connStr = getPostgreSQLConnectionString(DbCfg.Host, DbCfg.User, DbCfg.Passwd, DbCfg.Name, Param, DbCfg.SSLMode)
|
||||||
if host[0] == '/' { // looks like a unix socket
|
|
||||||
connStr = fmt.Sprintf("postgres://%s:%s@:%s/%s%ssslmode=%s&host=%s",
|
|
||||||
url.QueryEscape(DbCfg.User), url.QueryEscape(DbCfg.Passwd), port, DbCfg.Name, Param, DbCfg.SSLMode, host)
|
|
||||||
} else {
|
|
||||||
connStr = fmt.Sprintf("postgres://%s:%s@%s:%s/%s%ssslmode=%s",
|
|
||||||
url.QueryEscape(DbCfg.User), url.QueryEscape(DbCfg.Passwd), host, port, DbCfg.Name, Param, DbCfg.SSLMode)
|
|
||||||
}
|
|
||||||
case "mssql":
|
case "mssql":
|
||||||
host, port := parseMSSQLHostPort(DbCfg.Host)
|
host, port := parseMSSQLHostPort(DbCfg.Host)
|
||||||
connStr = fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;", host, port, DbCfg.Name, DbCfg.User, DbCfg.Passwd)
|
connStr = fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;", host, port, DbCfg.Name, DbCfg.User, DbCfg.Passwd)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2016 The Gogs Authors. All rights reserved.
|
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
@ -53,3 +54,42 @@ func Test_parsePostgreSQLHostPort(t *testing.T) {
|
||||||
assert.Equal(t, test.Port, port)
|
assert.Equal(t, test.Port, port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_getPostgreSQLConnectionString(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
Host string
|
||||||
|
Port string
|
||||||
|
User string
|
||||||
|
Passwd string
|
||||||
|
Name string
|
||||||
|
Param string
|
||||||
|
SSLMode string
|
||||||
|
Output string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Host: "/tmp/pg.sock",
|
||||||
|
Port: "4321",
|
||||||
|
User: "testuser",
|
||||||
|
Passwd: "space space !#$%^^%^```-=?=",
|
||||||
|
Name: "gitea",
|
||||||
|
Param: "",
|
||||||
|
SSLMode: "false",
|
||||||
|
Output: "postgres://testuser:space%20space%20%21%23$%25%5E%5E%25%5E%60%60%60-=%3F=@:5432/giteasslmode=false&host=/tmp/pg.sock",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Host: "localhost",
|
||||||
|
Port: "1234",
|
||||||
|
User: "pgsqlusername",
|
||||||
|
Passwd: "I love Gitea!",
|
||||||
|
Name: "gitea",
|
||||||
|
Param: "",
|
||||||
|
SSLMode: "true",
|
||||||
|
Output: "postgres://pgsqlusername:I%20love%20Gitea%21@localhost:5432/giteasslmode=true",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
connStr := getPostgreSQLConnectionString(test.Host, test.User, test.Passwd, test.Name, test.Param, test.SSLMode)
|
||||||
|
assert.Equal(t, test.Output, connStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,17 @@ func createOrUpdateIssueNotifications(e Engine, issue *Issue, notificationAuthor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue.loadRepo(e)
|
||||||
|
|
||||||
for _, watch := range watches {
|
for _, watch := range watches {
|
||||||
|
issue.Repo.Units = nil
|
||||||
|
if issue.IsPull && !issue.Repo.CheckUnitUser(watch.UserID, false, UnitTypePullRequests) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !issue.IsPull && !issue.Repo.CheckUnitUser(watch.UserID, false, UnitTypeIssues) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if err := notifyUser(watch.UserID); err != nil {
|
if err := notifyUser(watch.UserID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -154,12 +154,26 @@ func CreateOrganization(org, owner *User) (err error) {
|
||||||
Name: ownerTeamName,
|
Name: ownerTeamName,
|
||||||
Authorize: AccessModeOwner,
|
Authorize: AccessModeOwner,
|
||||||
NumMembers: 1,
|
NumMembers: 1,
|
||||||
UnitTypes: allRepUnitTypes,
|
|
||||||
}
|
}
|
||||||
if _, err = sess.Insert(t); err != nil {
|
if _, err = sess.Insert(t); err != nil {
|
||||||
return fmt.Errorf("insert owner team: %v", err)
|
return fmt.Errorf("insert owner team: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// insert units for team
|
||||||
|
var units = make([]TeamUnit, 0, len(allRepUnitTypes))
|
||||||
|
for _, tp := range allRepUnitTypes {
|
||||||
|
units = append(units, TeamUnit{
|
||||||
|
OrgID: org.ID,
|
||||||
|
TeamID: t.ID,
|
||||||
|
Type: tp,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = sess.Insert(&units); err != nil {
|
||||||
|
sess.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if _, err = sess.Insert(&TeamUser{
|
if _, err = sess.Insert(&TeamUser{
|
||||||
UID: owner.ID,
|
UID: owner.ID,
|
||||||
OrgID: org.ID,
|
OrgID: org.ID,
|
||||||
|
|
@ -238,6 +252,7 @@ func deleteOrg(e *xorm.Session, u *User) error {
|
||||||
&Team{OrgID: u.ID},
|
&Team{OrgID: u.ID},
|
||||||
&OrgUser{OrgID: u.ID},
|
&OrgUser{OrgID: u.ID},
|
||||||
&TeamUser{OrgID: u.ID},
|
&TeamUser{OrgID: u.ID},
|
||||||
|
&TeamUnit{OrgID: u.ID},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return fmt.Errorf("deleteBeans: %v", err)
|
return fmt.Errorf("deleteBeans: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
// Copyright 2016 The Gogs Authors. All rights reserved.
|
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
@ -10,7 +11,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
|
||||||
"github.com/go-xorm/xorm"
|
"github.com/go-xorm/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -28,15 +28,16 @@ type Team struct {
|
||||||
Members []*User `xorm:"-"`
|
Members []*User `xorm:"-"`
|
||||||
NumRepos int
|
NumRepos int
|
||||||
NumMembers int
|
NumMembers int
|
||||||
UnitTypes []UnitType `xorm:"json"`
|
Units []*TeamUnit `xorm:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUnitTypes returns unit types the team owned, empty means all the unit types
|
func (t *Team) getUnits(e Engine) (err error) {
|
||||||
func (t *Team) GetUnitTypes() []UnitType {
|
if t.Units != nil {
|
||||||
if len(t.UnitTypes) == 0 {
|
return nil
|
||||||
return allRepUnitTypes
|
|
||||||
}
|
}
|
||||||
return t.UnitTypes
|
|
||||||
|
t.Units, err = getUnitsByTeamID(e, t.ID)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasWriteAccess returns true if team has at least write level access mode.
|
// HasWriteAccess returns true if team has at least write level access mode.
|
||||||
|
|
@ -178,6 +179,11 @@ func (t *Team) removeRepository(e Engine, repo *Repository, recalculate bool) (e
|
||||||
if err = watchRepo(e, teamUser.UID, repo.ID, false); err != nil {
|
if err = watchRepo(e, teamUser.UID, repo.ID, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove all IssueWatches a user has subscribed to in the repositories
|
||||||
|
if err := removeIssueWatchersByRepoID(e, teamUser.UID, repo.ID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -209,11 +215,12 @@ func (t *Team) RemoveRepository(repoID int64) error {
|
||||||
|
|
||||||
// UnitEnabled returns if the team has the given unit type enabled
|
// UnitEnabled returns if the team has the given unit type enabled
|
||||||
func (t *Team) UnitEnabled(tp UnitType) bool {
|
func (t *Team) UnitEnabled(tp UnitType) bool {
|
||||||
if len(t.UnitTypes) == 0 {
|
if err := t.getUnits(x); err != nil {
|
||||||
return true
|
log.Warn("Error loading repository (ID: %d) units: %s", t.ID, err.Error())
|
||||||
}
|
}
|
||||||
for _, u := range t.UnitTypes {
|
|
||||||
if u == tp {
|
for _, unit := range t.Units {
|
||||||
|
if unit.Type == tp {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -270,6 +277,17 @@ func NewTeam(t *Team) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// insert units for team
|
||||||
|
if len(t.Units) > 0 {
|
||||||
|
for _, unit := range t.Units {
|
||||||
|
unit.TeamID = t.ID
|
||||||
|
}
|
||||||
|
if _, err = sess.Insert(&t.Units); err != nil {
|
||||||
|
sess.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update organization number of teams.
|
// Update organization number of teams.
|
||||||
if _, err = sess.Exec("UPDATE `user` SET num_teams=num_teams+1 WHERE id = ?", t.OrgID); err != nil {
|
if _, err = sess.Exec("UPDATE `user` SET num_teams=num_teams+1 WHERE id = ?", t.OrgID); err != nil {
|
||||||
sess.Rollback()
|
sess.Rollback()
|
||||||
|
|
@ -374,11 +392,34 @@ func DeleteTeam(t *Team) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := t.getMembers(sess); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Delete all accesses.
|
// Delete all accesses.
|
||||||
for _, repo := range t.Repos {
|
for _, repo := range t.Repos {
|
||||||
if err := repo.recalculateTeamAccesses(sess, t.ID); err != nil {
|
if err := repo.recalculateTeamAccesses(sess, t.ID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove watches from all users and now unaccessible repos
|
||||||
|
for _, user := range t.Members {
|
||||||
|
has, err := hasAccess(sess, user.ID, repo, AccessModeRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if has {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = watchRepo(sess, user.ID, repo.ID, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove all IssueWatches a user has subscribed to in the repositories
|
||||||
|
if err = removeIssueWatchersByRepoID(sess, user.ID, repo.ID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete team-repo
|
// Delete team-repo
|
||||||
|
|
@ -396,6 +437,13 @@ func DeleteTeam(t *Team) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete team-unit.
|
||||||
|
if _, err := sess.
|
||||||
|
Where("team_id=?", t.ID).
|
||||||
|
Delete(new(TeamUnit)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Delete team.
|
// Delete team.
|
||||||
if _, err := sess.ID(t.ID).Delete(new(Team)); err != nil {
|
if _, err := sess.ID(t.ID).Delete(new(Team)); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -518,6 +566,10 @@ func AddTeamMember(team *Team, userID int64) error {
|
||||||
if err := repo.recalculateTeamAccesses(sess, 0); err != nil {
|
if err := repo.recalculateTeamAccesses(sess, 0); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = watchRepo(sess, userID, repo.ID, true); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sess.Commit()
|
return sess.Commit()
|
||||||
|
|
@ -558,6 +610,23 @@ func removeTeamMember(e *xorm.Session, team *Team, userID int64) error {
|
||||||
if err := repo.recalculateTeamAccesses(e, 0); err != nil {
|
if err := repo.recalculateTeamAccesses(e, 0); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove watches from now unaccessible
|
||||||
|
has, err := hasAccess(e, userID, repo, AccessModeRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if has {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = watchRepo(e, userID, repo.ID, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove all IssueWatches a user has subscribed to in the repositories
|
||||||
|
if err := removeIssueWatchersByRepoID(e, userID, repo.ID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the user is a member of any team in the organization.
|
// Check if the user is a member of any team in the organization.
|
||||||
|
|
@ -646,3 +715,47 @@ func GetTeamsWithAccessToRepo(orgID, repoID int64, mode AccessMode) ([]*Team, er
|
||||||
And("team_repo.repo_id = ?", repoID).
|
And("team_repo.repo_id = ?", repoID).
|
||||||
Find(&teams)
|
Find(&teams)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ___________ ____ ___ .__ __
|
||||||
|
// \__ ___/___ _____ _____ | | \____ |__|/ |_
|
||||||
|
// | |_/ __ \\__ \ / \| | / \| \ __\
|
||||||
|
// | |\ ___/ / __ \| Y Y \ | / | \ || |
|
||||||
|
// |____| \___ >____ /__|_| /______/|___| /__||__|
|
||||||
|
// \/ \/ \/ \/
|
||||||
|
|
||||||
|
// TeamUnit describes all units of a repository
|
||||||
|
type TeamUnit struct {
|
||||||
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
OrgID int64 `xorm:"INDEX"`
|
||||||
|
TeamID int64 `xorm:"UNIQUE(s)"`
|
||||||
|
Type UnitType `xorm:"UNIQUE(s)"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unit returns Unit
|
||||||
|
func (t *TeamUnit) Unit() Unit {
|
||||||
|
return Units[t.Type]
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUnitsByTeamID(e Engine, teamID int64) (units []*TeamUnit, err error) {
|
||||||
|
return units, e.Where("team_id = ?", teamID).Find(&units)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTeamUnits updates a teams's units
|
||||||
|
func UpdateTeamUnits(team *Team, units []TeamUnit) (err error) {
|
||||||
|
sess := x.NewSession()
|
||||||
|
defer sess.Close()
|
||||||
|
if err = sess.Begin(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = sess.Where("team_id = ?", team.ID).Delete(new(TeamUnit)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = sess.Insert(units); err != nil {
|
||||||
|
sess.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sess.Commit()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -489,8 +489,8 @@ func TestAccessibleReposEnv_CountRepos(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, expectedCount, count)
|
assert.EqualValues(t, expectedCount, count)
|
||||||
}
|
}
|
||||||
testSuccess(2, 2)
|
testSuccess(2, 3)
|
||||||
testSuccess(4, 1)
|
testSuccess(4, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccessibleReposEnv_RepoIDs(t *testing.T) {
|
func TestAccessibleReposEnv_RepoIDs(t *testing.T) {
|
||||||
|
|
@ -503,8 +503,8 @@ func TestAccessibleReposEnv_RepoIDs(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, expectedRepoIDs, repoIDs)
|
assert.Equal(t, expectedRepoIDs, repoIDs)
|
||||||
}
|
}
|
||||||
testSuccess(2, 1, 100, []int64{3, 5})
|
testSuccess(2, 1, 100, []int64{3, 5, 32})
|
||||||
testSuccess(4, 0, 100, []int64{3})
|
testSuccess(4, 0, 100, []int64{3, 32})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccessibleReposEnv_Repos(t *testing.T) {
|
func TestAccessibleReposEnv_Repos(t *testing.T) {
|
||||||
|
|
@ -522,8 +522,8 @@ func TestAccessibleReposEnv_Repos(t *testing.T) {
|
||||||
}
|
}
|
||||||
assert.Equal(t, expectedRepos, repos)
|
assert.Equal(t, expectedRepos, repos)
|
||||||
}
|
}
|
||||||
testSuccess(2, []int64{3, 5})
|
testSuccess(2, []int64{3, 5, 32})
|
||||||
testSuccess(4, []int64{3})
|
testSuccess(4, []int64{3, 32})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccessibleReposEnv_MirrorRepos(t *testing.T) {
|
func TestAccessibleReposEnv_MirrorRepos(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -448,6 +448,11 @@ func DeleteReleaseByID(id int64, u *User, delTag bool) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rel.Repo = repo
|
||||||
|
if err = rel.LoadAttributes(); err != nil {
|
||||||
|
return fmt.Errorf("LoadAttributes: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
mode, _ := accessLevel(x, u.ID, rel.Repo)
|
mode, _ := accessLevel(x, u.ID, rel.Repo)
|
||||||
if err := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
|
if err := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
|
||||||
Action: api.HookReleaseDeleted,
|
Action: api.HookReleaseDeleted,
|
||||||
|
|
|
||||||
|
|
@ -365,22 +365,14 @@ func (repo *Repository) getUnitsByUserID(e Engine, userID int64, isAdmin bool) (
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var allTypes = make(map[UnitType]struct{}, len(allRepUnitTypes))
|
|
||||||
for _, team := range teams {
|
|
||||||
// Administrators can not be limited
|
|
||||||
if team.Authorize >= AccessModeAdmin {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
for _, unitType := range team.UnitTypes {
|
|
||||||
allTypes[unitType] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// unique
|
// unique
|
||||||
var newRepoUnits = make([]*RepoUnit, 0, len(repo.Units))
|
var newRepoUnits = make([]*RepoUnit, 0, len(repo.Units))
|
||||||
for _, u := range repo.Units {
|
for _, u := range repo.Units {
|
||||||
if _, ok := allTypes[u.Type]; ok {
|
for _, team := range teams {
|
||||||
newRepoUnits = append(newRepoUnits, u)
|
if team.UnitEnabled(u.Type) {
|
||||||
|
newRepoUnits = append(newRepoUnits, u)
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1848,6 +1840,12 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
|
||||||
if _, err = sess.In("issue_id", issueIDs).Delete(&IssueUser{}); err != nil {
|
if _, err = sess.In("issue_id", issueIDs).Delete(&IssueUser{}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if _, err = sess.In("issue_id", issueIDs).Delete(&Reaction{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = sess.In("issue_id", issueIDs).Delete(&IssueWatch{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
attachments := make([]*Attachment, 0, 5)
|
attachments := make([]*Attachment, 0, 5)
|
||||||
if err = sess.
|
if err = sess.
|
||||||
|
|
|
||||||
|
|
@ -172,5 +172,14 @@ func (repo *Repository) DeleteCollaboration(uid int64) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = watchRepo(sess, uid, repo.ID, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove all IssueWatches a user has subscribed to in the repository
|
||||||
|
if err := removeIssueWatchersByRepoID(sess, uid, repo.ID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return sess.Commit()
|
return sess.Commit()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -147,10 +147,10 @@ func TestSearchRepositoryByName(t *testing.T) {
|
||||||
count: 14},
|
count: 14},
|
||||||
{name: "AllPublic/PublicRepositoriesOfUserIncludingCollaborative",
|
{name: "AllPublic/PublicRepositoriesOfUserIncludingCollaborative",
|
||||||
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, AllPublic: true},
|
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, AllPublic: true},
|
||||||
count: 15},
|
count: 16},
|
||||||
{name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative",
|
{name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative",
|
||||||
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true},
|
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true},
|
||||||
count: 19},
|
count: 20},
|
||||||
{name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborativeByName",
|
{name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborativeByName",
|
||||||
opts: &SearchRepoOptions{Keyword: "test", Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true},
|
opts: &SearchRepoOptions{Keyword: "test", Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true},
|
||||||
count: 13},
|
count: 13},
|
||||||
|
|
@ -159,7 +159,7 @@ func TestSearchRepositoryByName(t *testing.T) {
|
||||||
count: 11},
|
count: 11},
|
||||||
{name: "AllPublic/PublicRepositoriesOfOrganization",
|
{name: "AllPublic/PublicRepositoriesOfOrganization",
|
||||||
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 17, AllPublic: true, Collaborate: util.OptionalBoolFalse},
|
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 17, AllPublic: true, Collaborate: util.OptionalBoolFalse},
|
||||||
count: 15},
|
count: 16},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,23 @@ func notifyWatchers(e Engine, act *Action) error {
|
||||||
|
|
||||||
act.ID = 0
|
act.ID = 0
|
||||||
act.UserID = watches[i].UserID
|
act.UserID = watches[i].UserID
|
||||||
|
act.Repo.Units = nil
|
||||||
|
|
||||||
|
switch act.OpType {
|
||||||
|
case ActionCommitRepo, ActionPushTag, ActionDeleteTag, ActionDeleteBranch:
|
||||||
|
if !act.Repo.CheckUnitUser(act.UserID, false, UnitTypeCode) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case ActionCreateIssue, ActionCommentIssue, ActionCloseIssue, ActionReopenIssue:
|
||||||
|
if !act.Repo.CheckUnitUser(act.UserID, false, UnitTypeIssues) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case ActionCreatePullRequest, ActionMergePullRequest, ActionClosePullRequest, ActionReopenPullRequest:
|
||||||
|
if !act.Repo.CheckUnitUser(act.UserID, false, UnitTypePullRequests) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if _, err = e.InsertOne(act); err != nil {
|
if _, err = e.InsertOne(act); err != nil {
|
||||||
return fmt.Errorf("insert new action: %v", err)
|
return fmt.Errorf("insert new action: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
@ -20,6 +21,8 @@ func init() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var topicPattern = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`)
|
||||||
|
|
||||||
// Topic represents a topic of repositories
|
// Topic represents a topic of repositories
|
||||||
type Topic struct {
|
type Topic struct {
|
||||||
ID int64
|
ID int64
|
||||||
|
|
@ -51,6 +54,11 @@ func (err ErrTopicNotExist) Error() string {
|
||||||
return fmt.Sprintf("topic is not exist [name: %s]", err.Name)
|
return fmt.Sprintf("topic is not exist [name: %s]", err.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ValidateTopic checks topics by length and match pattern rules
|
||||||
|
func ValidateTopic(topic string) bool {
|
||||||
|
return len(topic) <= 35 && topicPattern.MatchString(topic)
|
||||||
|
}
|
||||||
|
|
||||||
// GetTopicByName retrieves topic by name
|
// GetTopicByName retrieves topic by name
|
||||||
func GetTopicByName(name string) (*Topic, error) {
|
func GetTopicByName(name string) (*Topic, error) {
|
||||||
var topic Topic
|
var topic Topic
|
||||||
|
|
@ -182,6 +190,13 @@ func SaveTopics(repoID int64, topicNames ...string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
topicNames = topicNames[:0]
|
||||||
|
if err := sess.Table("topic").Cols("name").
|
||||||
|
Join("INNER", "repo_topic", "topic.id = repo_topic.topic_id").
|
||||||
|
Where("repo_topic.repo_id = ?", repoID).Find(&topicNames); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := sess.ID(repoID).Cols("topics").Update(&Repository{
|
if _, err := sess.ID(repoID).Cols("topics").Update(&Repository{
|
||||||
Topics: topicNames,
|
Topics: topicNames,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -55,3 +55,16 @@ func TestAddTopic(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 2, len(topics))
|
assert.EqualValues(t, 2, len(topics))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTopicValidator(t *testing.T) {
|
||||||
|
assert.True(t, ValidateTopic("12345"))
|
||||||
|
assert.True(t, ValidateTopic("2-test"))
|
||||||
|
assert.True(t, ValidateTopic("test-3"))
|
||||||
|
assert.True(t, ValidateTopic("first"))
|
||||||
|
assert.True(t, ValidateTopic("second-test-topic"))
|
||||||
|
assert.True(t, ValidateTopic("third-project-topic-with-max-length"))
|
||||||
|
|
||||||
|
assert.False(t, ValidateTopic("$fourth-test,topic"))
|
||||||
|
assert.False(t, ValidateTopic("-fifth-test-topic"))
|
||||||
|
assert.False(t, ValidateTopic("sixth-go-project-topic-with-excess-length"))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -546,28 +546,46 @@ func (u *User) GetRepositories(page, pageSize int) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRepositoryIDs returns repositories IDs where user owned
|
// GetRepositoryIDs returns repositories IDs where user owned and has unittypes
|
||||||
func (u *User) GetRepositoryIDs() ([]int64, error) {
|
func (u *User) GetRepositoryIDs(units ...UnitType) ([]int64, error) {
|
||||||
var ids []int64
|
var ids []int64
|
||||||
return ids, x.Table("repository").Cols("id").Where("owner_id = ?", u.ID).Find(&ids)
|
|
||||||
|
sess := x.Table("repository").Cols("repository.id")
|
||||||
|
|
||||||
|
if len(units) > 0 {
|
||||||
|
sess = sess.Join("INNER", "repo_unit", "repository.id = repo_unit.repo_id")
|
||||||
|
sess = sess.In("repo_unit.type", units)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids, sess.Where("owner_id = ?", u.ID).Find(&ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOrgRepositoryIDs returns repositories IDs where user's team owned
|
// GetOrgRepositoryIDs returns repositories IDs where user's team owned and has unittypes
|
||||||
func (u *User) GetOrgRepositoryIDs() ([]int64, error) {
|
func (u *User) GetOrgRepositoryIDs(units ...UnitType) ([]int64, error) {
|
||||||
var ids []int64
|
var ids []int64
|
||||||
return ids, x.Table("repository").
|
|
||||||
|
sess := x.Table("repository").
|
||||||
Cols("repository.id").
|
Cols("repository.id").
|
||||||
Join("INNER", "team_user", "repository.owner_id = team_user.org_id AND team_user.uid = ?", u.ID).
|
Join("INNER", "team_user", "repository.owner_id = team_user.org_id").
|
||||||
|
Join("INNER", "team_repo", "repository.is_private != ? OR (team_user.team_id = team_repo.team_id AND repository.id = team_repo.repo_id)", true)
|
||||||
|
|
||||||
|
if len(units) > 0 {
|
||||||
|
sess = sess.Join("INNER", "team_unit", "team_unit.team_id = team_user.team_id")
|
||||||
|
sess = sess.In("team_unit.type", units)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids, sess.
|
||||||
|
Where("team_user.uid = ?", u.ID).
|
||||||
GroupBy("repository.id").Find(&ids)
|
GroupBy("repository.id").Find(&ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccessRepoIDs returns all repositories IDs where user's or user is a team member organizations
|
// GetAccessRepoIDs returns all repositories IDs where user's or user is a team member organizations
|
||||||
func (u *User) GetAccessRepoIDs() ([]int64, error) {
|
func (u *User) GetAccessRepoIDs(units ...UnitType) ([]int64, error) {
|
||||||
ids, err := u.GetRepositoryIDs()
|
ids, err := u.GetRepositoryIDs(units...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ids2, err := u.GetOrgRepositoryIDs()
|
ids2, err := u.GetOrgRepositoryIDs(units...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -159,3 +159,25 @@ func BenchmarkHashPassword(b *testing.B) {
|
||||||
u.HashPassword(pass)
|
u.HashPassword(pass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetOrgRepositoryIDs(t *testing.T) {
|
||||||
|
assert.NoError(t, PrepareTestDatabase())
|
||||||
|
user2 := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
||||||
|
user4 := AssertExistsAndLoadBean(t, &User{ID: 4}).(*User)
|
||||||
|
user5 := AssertExistsAndLoadBean(t, &User{ID: 5}).(*User)
|
||||||
|
|
||||||
|
accessibleRepos, err := user2.GetOrgRepositoryIDs()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
// User 2's team has access to private repos 3, 5, repo 32 is a public repo of the organization
|
||||||
|
assert.Equal(t, []int64{3, 5, 32}, accessibleRepos)
|
||||||
|
|
||||||
|
accessibleRepos, err = user4.GetOrgRepositoryIDs()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
// User 4's team has access to private repo 3, repo 32 is a public repo of the organization
|
||||||
|
assert.Equal(t, []int64{3, 32}, accessibleRepos)
|
||||||
|
|
||||||
|
accessibleRepos, err = user5.GetOrgRepositoryIDs()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
// User 5's team has no access to any repo
|
||||||
|
assert.Len(t, accessibleRepos, 0)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,6 @@ func Toggle(options *ToggleOptions) macaron.Handler {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check non-logged users landing page.
|
|
||||||
if !ctx.IsSigned && ctx.Req.RequestURI == "/" && setting.LandingPageURL != setting.LandingPageHome {
|
|
||||||
ctx.Redirect(setting.AppSubURL + string(setting.LandingPageURL))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Redirect to dashboard if user tries to visit any non-login page.
|
// Redirect to dashboard if user tries to visit any non-login page.
|
||||||
if options.SignOutRequired && ctx.IsSigned && ctx.Req.RequestURI != "/" {
|
if options.SignOutRequired && ctx.IsSigned && ctx.Req.RequestURI != "/" {
|
||||||
ctx.Redirect(setting.AppSubURL + "/")
|
ctx.Redirect(setting.AppSubURL + "/")
|
||||||
|
|
|
||||||
|
|
@ -469,6 +469,9 @@ func shortLinkProcessorFull(ctx *postProcessCtx, node *html.Node, noLink bool) {
|
||||||
} else {
|
} else {
|
||||||
link = strings.Replace(link, " ", "-", -1)
|
link = strings.Replace(link, " ", "-", -1)
|
||||||
}
|
}
|
||||||
|
if !strings.Contains(link, "/") {
|
||||||
|
link = url.PathEscape(link)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
urlPrefix := ctx.urlPrefix
|
urlPrefix := ctx.urlPrefix
|
||||||
if image {
|
if image {
|
||||||
|
|
|
||||||
|
|
@ -82,12 +82,18 @@ func TestRender_ShortLinks(t *testing.T) {
|
||||||
rawtree := util.URLJoin(AppSubURL, "raw", "master")
|
rawtree := util.URLJoin(AppSubURL, "raw", "master")
|
||||||
url := util.URLJoin(tree, "Link")
|
url := util.URLJoin(tree, "Link")
|
||||||
otherURL := util.URLJoin(tree, "Other-Link")
|
otherURL := util.URLJoin(tree, "Other-Link")
|
||||||
|
encodedURL := util.URLJoin(tree, "Link%3F")
|
||||||
imgurl := util.URLJoin(rawtree, "Link.jpg")
|
imgurl := util.URLJoin(rawtree, "Link.jpg")
|
||||||
otherImgurl := util.URLJoin(rawtree, "Link+Other.jpg")
|
otherImgurl := util.URLJoin(rawtree, "Link+Other.jpg")
|
||||||
|
encodedImgurl := util.URLJoin(rawtree, "Link+%23.jpg")
|
||||||
|
notencodedImgurl := util.URLJoin(rawtree, "some", "path", "Link+#.jpg")
|
||||||
urlWiki := util.URLJoin(AppSubURL, "wiki", "Link")
|
urlWiki := util.URLJoin(AppSubURL, "wiki", "Link")
|
||||||
otherURLWiki := util.URLJoin(AppSubURL, "wiki", "Other-Link")
|
otherURLWiki := util.URLJoin(AppSubURL, "wiki", "Other-Link")
|
||||||
|
encodedURLWiki := util.URLJoin(AppSubURL, "wiki", "Link%3F")
|
||||||
imgurlWiki := util.URLJoin(AppSubURL, "wiki", "raw", "Link.jpg")
|
imgurlWiki := util.URLJoin(AppSubURL, "wiki", "raw", "Link.jpg")
|
||||||
otherImgurlWiki := util.URLJoin(AppSubURL, "wiki", "raw", "Link+Other.jpg")
|
otherImgurlWiki := util.URLJoin(AppSubURL, "wiki", "raw", "Link+Other.jpg")
|
||||||
|
encodedImgurlWiki := util.URLJoin(AppSubURL, "wiki", "raw", "Link+%23.jpg")
|
||||||
|
notencodedImgurlWiki := util.URLJoin(AppSubURL, "wiki", "raw", "some", "path", "Link+#.jpg")
|
||||||
favicon := "http://google.com/favicon.ico"
|
favicon := "http://google.com/favicon.ico"
|
||||||
|
|
||||||
test(
|
test(
|
||||||
|
|
@ -134,4 +140,24 @@ func TestRender_ShortLinks(t *testing.T) {
|
||||||
"[[Link]] [[Other Link]]",
|
"[[Link]] [[Other Link]]",
|
||||||
`<p><a href="`+url+`" rel="nofollow">Link</a> <a href="`+otherURL+`" rel="nofollow">Other Link</a></p>`,
|
`<p><a href="`+url+`" rel="nofollow">Link</a> <a href="`+otherURL+`" rel="nofollow">Other Link</a></p>`,
|
||||||
`<p><a href="`+urlWiki+`" rel="nofollow">Link</a> <a href="`+otherURLWiki+`" rel="nofollow">Other Link</a></p>`)
|
`<p><a href="`+urlWiki+`" rel="nofollow">Link</a> <a href="`+otherURLWiki+`" rel="nofollow">Other Link</a></p>`)
|
||||||
|
test(
|
||||||
|
"[[Link?]]",
|
||||||
|
`<p><a href="`+encodedURL+`" rel="nofollow">Link?</a></p>`,
|
||||||
|
`<p><a href="`+encodedURLWiki+`" rel="nofollow">Link?</a></p>`)
|
||||||
|
test(
|
||||||
|
"[[Link]] [[Other Link]] [[Link?]]",
|
||||||
|
`<p><a href="`+url+`" rel="nofollow">Link</a> <a href="`+otherURL+`" rel="nofollow">Other Link</a> <a href="`+encodedURL+`" rel="nofollow">Link?</a></p>`,
|
||||||
|
`<p><a href="`+urlWiki+`" rel="nofollow">Link</a> <a href="`+otherURLWiki+`" rel="nofollow">Other Link</a> <a href="`+encodedURLWiki+`" rel="nofollow">Link?</a></p>`)
|
||||||
|
test(
|
||||||
|
"[[Link #.jpg]]",
|
||||||
|
`<p><a href="`+encodedImgurl+`" rel="nofollow"><img src="`+encodedImgurl+`"/></a></p>`,
|
||||||
|
`<p><a href="`+encodedImgurlWiki+`" rel="nofollow"><img src="`+encodedImgurlWiki+`"/></a></p>`)
|
||||||
|
test(
|
||||||
|
"[[Name|Link #.jpg|alt=\"AltName\"|title='Title']]",
|
||||||
|
`<p><a href="`+encodedImgurl+`" rel="nofollow"><img src="`+encodedImgurl+`" title="Title" alt="AltName"/></a></p>`,
|
||||||
|
`<p><a href="`+encodedImgurlWiki+`" rel="nofollow"><img src="`+encodedImgurlWiki+`" title="Title" alt="AltName"/></a></p>`)
|
||||||
|
test(
|
||||||
|
"[[some/path/Link #.jpg]]",
|
||||||
|
`<p><a href="`+notencodedImgurl+`" rel="nofollow"><img src="`+notencodedImgurl+`"/></a></p>`,
|
||||||
|
`<p><a href="`+notencodedImgurlWiki+`" rel="nofollow"><img src="`+notencodedImgurlWiki+`"/></a></p>`)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,7 @@ func RenderCommitBody(msg, urlPrefix string, metas map[string]string) template.H
|
||||||
|
|
||||||
// IsMultilineCommitMessage checks to see if a commit message contains multiple lines.
|
// IsMultilineCommitMessage checks to see if a commit message contains multiple lines.
|
||||||
func IsMultilineCommitMessage(msg string) bool {
|
func IsMultilineCommitMessage(msg string) bool {
|
||||||
return strings.Count(strings.TrimSpace(msg), "\n") > 1
|
return strings.Count(strings.TrimSpace(msg), "\n") >= 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actioner describes an action
|
// Actioner describes an action
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OptionalBool a boolean that can be "null"
|
// OptionalBool a boolean that can be "null"
|
||||||
|
|
@ -78,6 +79,18 @@ func URLJoin(base string, elems ...string) string {
|
||||||
return joinedURL
|
return joinedURL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsExternalURL checks if rawURL points to an external URL like http://example.com
|
||||||
|
func IsExternalURL(rawURL string) bool {
|
||||||
|
parsed, err := url.Parse(rawURL)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if len(parsed.Host) != 0 && strings.Replace(parsed.Host, "www.", "", 1) != strings.Replace(setting.Domain, "www.", "", 1) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Min min of two ints
|
// Min min of two ints
|
||||||
func Min(a, b int) int {
|
func Min(a, b int) int {
|
||||||
if a > b {
|
if a > b {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ package util
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -42,3 +44,36 @@ func TestURLJoin(t *testing.T) {
|
||||||
assert.Equal(t, test.Expected, URLJoin(test.Base, test.Elements...))
|
assert.Equal(t, test.Expected, URLJoin(test.Base, test.Elements...))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsExternalURL(t *testing.T) {
|
||||||
|
setting.Domain = "try.gitea.io"
|
||||||
|
type test struct {
|
||||||
|
Expected bool
|
||||||
|
RawURL string
|
||||||
|
}
|
||||||
|
newTest := func(expected bool, rawURL string) test {
|
||||||
|
return test{Expected: expected, RawURL: rawURL}
|
||||||
|
}
|
||||||
|
for _, test := range []test{
|
||||||
|
newTest(false,
|
||||||
|
"https://try.gitea.io"),
|
||||||
|
newTest(true,
|
||||||
|
"https://example.com/"),
|
||||||
|
newTest(true,
|
||||||
|
"//example.com"),
|
||||||
|
newTest(true,
|
||||||
|
"http://example.com"),
|
||||||
|
newTest(false,
|
||||||
|
"a/"),
|
||||||
|
newTest(false,
|
||||||
|
"https://try.gitea.io/test?param=false"),
|
||||||
|
newTest(false,
|
||||||
|
"test?param=false"),
|
||||||
|
newTest(false,
|
||||||
|
"//try.gitea.io/test?param=false"),
|
||||||
|
newTest(false,
|
||||||
|
"/hey/hey/hey#3244"),
|
||||||
|
} {
|
||||||
|
assert.Equal(t, test.Expected, IsExternalURL(test.RawURL))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,6 @@ has_unconfirmed_mail=Здравейте %s, имате непотвърден а
|
||||||
resend_mail=Щракнете тук, за да се изпрати ново писмо за потвърждение
|
resend_mail=Щракнете тук, за да се изпрати ново писмо за потвърждение
|
||||||
reset_password=Нулиране на паролата
|
reset_password=Нулиране на паролата
|
||||||
reset_password_helper=Щракнете тук, за да нулирате паролата си
|
reset_password_helper=Щракнете тук, за да нулирате паролата си
|
||||||
password_too_short=Размерът на паролата не може да бъде по-малък от %d знака.
|
|
||||||
|
|
||||||
[mail]
|
[mail]
|
||||||
activate_account=Моля активирайте Вашия профил
|
activate_account=Моля активирайте Вашия профил
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,6 @@ has_unconfirmed_mail=Zdravím, %s, máte nepotvrzenou e-mailovou adresu (<b>%s</
|
||||||
resend_mail=Klikněte zde pro odeslání aktivačního e-mailu
|
resend_mail=Klikněte zde pro odeslání aktivačního e-mailu
|
||||||
reset_password=Obnova vašeho hesla
|
reset_password=Obnova vašeho hesla
|
||||||
reset_password_helper=Klikněte zde pro obnovu vašeho hesla
|
reset_password_helper=Klikněte zde pro obnovu vašeho hesla
|
||||||
password_too_short=Délka hesla musí být minimálně %d znaků.
|
|
||||||
|
|
||||||
[mail]
|
[mail]
|
||||||
activate_account=Prosíme, aktivujte si váš účet
|
activate_account=Prosíme, aktivujte si váš účet
|
||||||
|
|
|
||||||
|
|
@ -83,12 +83,12 @@ host=Host
|
||||||
user=Benutzername
|
user=Benutzername
|
||||||
password=Passwort
|
password=Passwort
|
||||||
db_name=Datenbankname
|
db_name=Datenbankname
|
||||||
db_helper=Hinweis für MySQL-Benutzer: Bitte verwende das InnoDB Speichersubsystem und den Zeichensatz "utf8_general_ci".
|
db_helper=Hinweis für MySQL-Benutzer: Bitte verwende das InnoDB-Speichersubsystem und den Zeichensatz „utf8_general_ci“.
|
||||||
ssl_mode=SSL
|
ssl_mode=SSL
|
||||||
path=Pfad
|
path=Pfad
|
||||||
sqlite_helper=Der Dateipfad zur SQLite3- oder TiDB-Datenbank. <br>Bitte verwende einen absoluten Pfad, wenn Gitea als Service gestartet wird.
|
sqlite_helper=Der Dateipfad zur SQLite3- oder TiDB-Datenbank. <br>Bitte verwende einen absoluten Pfad, wenn Gitea als Service gestartet wird.
|
||||||
err_empty_db_path=Der SQLite3 oder TiDB Datenbankpfad darf nicht leer sein.
|
err_empty_db_path=Der SQLite3- oder TiDB-Datenbankpfad darf nicht leer sein.
|
||||||
err_invalid_tidb_name=Der TiDB Datenbankname darf nicht die Zeichen "." und "-" enthalten.
|
err_invalid_tidb_name=Der TiDB-Datenbankname darf nicht die Zeichen „.“ und „-“ enthalten.
|
||||||
no_admin_and_disable_registration=Du kannst Selbst-Registrierungen nicht deaktivieren, ohne ein Administratorkonto zu erstellen.
|
no_admin_and_disable_registration=Du kannst Selbst-Registrierungen nicht deaktivieren, ohne ein Administratorkonto zu erstellen.
|
||||||
err_empty_admin_password=Das Administrator-Passwort darf nicht leer sein.
|
err_empty_admin_password=Das Administrator-Passwort darf nicht leer sein.
|
||||||
|
|
||||||
|
|
@ -97,17 +97,17 @@ app_name=Seitentitel
|
||||||
app_name_helper=Du kannst hier den Namen deines Unternehmens eingeben.
|
app_name_helper=Du kannst hier den Namen deines Unternehmens eingeben.
|
||||||
repo_path=Repository-Verzeichnis
|
repo_path=Repository-Verzeichnis
|
||||||
repo_path_helper=Remote-Git-Repositories werden in diesem Verzeichnis gespeichert.
|
repo_path_helper=Remote-Git-Repositories werden in diesem Verzeichnis gespeichert.
|
||||||
lfs_path=Git LFS-Wurzelpfad
|
lfs_path=Git-LFS-Wurzelpfad
|
||||||
lfs_path_helper=In diesem Verzeichnis werden die Dateien von Git LFS abgespeichert. Leer lassen um LFS zu deaktivieren.
|
lfs_path_helper=In diesem Verzeichnis werden die Dateien von Git LFS abgespeichert. Leer lassen um LFS zu deaktivieren.
|
||||||
run_user=Ausführen als
|
run_user=Ausführen als
|
||||||
run_user_helper=Gebe den Betriebssystem-Benutzernamen ein, unter welchem Gitea laufen soll. Beachte, dass dieser Nutzer Zugriff auf den Repository-Ordner haben muss.
|
run_user_helper=Gebe den Betriebssystem-Benutzernamen ein, unter welchem Gitea laufen soll. Beachte, dass dieser Nutzer Zugriff auf den Repository-Ordner haben muss.
|
||||||
domain=SSH Server-Domain
|
domain=SSH-Server-Domain
|
||||||
domain_helper=Domain oder Host-Adresse für die SSH-URL.
|
domain_helper=Domain oder Host-Adresse für die SSH-URL.
|
||||||
ssh_port=SSH Server Port
|
ssh_port=SSH-Server-Port
|
||||||
ssh_port_helper=Der Port deines SSH-Servers. Leer lassen um SSH zu deaktivieren.
|
ssh_port_helper=Der Port deines SSH-Servers. Leer lassen um SSH zu deaktivieren.
|
||||||
http_port=Gitea HTTP-Listen-Port
|
http_port=Gitea-HTTP-Listen-Port
|
||||||
http_port_helper=Port unter dem der Gitea Web Server laufen soll.
|
http_port_helper=Port, unter dem der Gitea-Webserver laufen soll.
|
||||||
app_url=Gitea Basis-URL
|
app_url=Gitea-Basis-URL
|
||||||
app_url_helper=Adresse für HTTP(S)-Klon-URLs und E-Mail-Benachrichtigungen.
|
app_url_helper=Adresse für HTTP(S)-Klon-URLs und E-Mail-Benachrichtigungen.
|
||||||
log_root_path=Logdateipfad
|
log_root_path=Logdateipfad
|
||||||
log_root_path_helper=Log-Dateien werden in diesem Verzeichnis gespeichert.
|
log_root_path_helper=Log-Dateien werden in diesem Verzeichnis gespeichert.
|
||||||
|
|
@ -117,8 +117,8 @@ email_title=E-Mail-Einstellungen
|
||||||
smtp_host=SMTP-Server
|
smtp_host=SMTP-Server
|
||||||
smtp_from=E-Mail senden als
|
smtp_from=E-Mail senden als
|
||||||
smtp_from_helper=E-Mail-Adresse, die von Gitea genutzt werden soll. Bitte gib die E-Mail-Adresse im '"Name" <email@example.com>'-Format ein.
|
smtp_from_helper=E-Mail-Adresse, die von Gitea genutzt werden soll. Bitte gib die E-Mail-Adresse im '"Name" <email@example.com>'-Format ein.
|
||||||
mailer_user=SMTP Benutzername
|
mailer_user=SMTP-Benutzername
|
||||||
mailer_password=SMTP Passwort
|
mailer_password=SMTP-Passwort
|
||||||
register_confirm=E-Mail-Bestätigung benötigt zum Registrieren
|
register_confirm=E-Mail-Bestätigung benötigt zum Registrieren
|
||||||
mail_notify=E-Mail-Benachrichtigungen aktivieren
|
mail_notify=E-Mail-Benachrichtigungen aktivieren
|
||||||
server_service_title=Sonstige Server- und Drittserviceeinstellungen
|
server_service_title=Sonstige Server- und Drittserviceeinstellungen
|
||||||
|
|
@ -131,9 +131,9 @@ federated_avatar_lookup_popup=Föderierte Profilbilder via Libravatar aktivieren
|
||||||
disable_registration=Registrierung deaktivieren
|
disable_registration=Registrierung deaktivieren
|
||||||
disable_registration_popup=Registrierung neuer Benutzer deaktivieren. Nur Administratoren werden neue Benutzerkonten anlegen können.
|
disable_registration_popup=Registrierung neuer Benutzer deaktivieren. Nur Administratoren werden neue Benutzerkonten anlegen können.
|
||||||
allow_only_external_registration_popup=Registrierung nur über externe Services aktiveren.
|
allow_only_external_registration_popup=Registrierung nur über externe Services aktiveren.
|
||||||
openid_signin=OpenID Anmeldung aktivieren
|
openid_signin=OpenID-Anmeldung aktivieren
|
||||||
openid_signin_popup=Benutzeranmeldung via OpenID aktivieren.
|
openid_signin_popup=Benutzeranmeldung via OpenID aktivieren.
|
||||||
openid_signup=OpenID Selbstregistrierung aktivieren
|
openid_signup=OpenID-Selbstregistrierung aktivieren
|
||||||
openid_signup_popup=OpenID-basierte Selbstregistrierung aktivieren.
|
openid_signup_popup=OpenID-basierte Selbstregistrierung aktivieren.
|
||||||
enable_captcha=CAPTCHA aktivieren
|
enable_captcha=CAPTCHA aktivieren
|
||||||
enable_captcha_popup=Captcha-Eingabe bei der Registrierung erforderlich.
|
enable_captcha_popup=Captcha-Eingabe bei der Registrierung erforderlich.
|
||||||
|
|
@ -147,10 +147,10 @@ confirm_password=Passwort bestätigen
|
||||||
admin_email=E-Mail-Adresse
|
admin_email=E-Mail-Adresse
|
||||||
install_btn_confirm=Gitea installieren
|
install_btn_confirm=Gitea installieren
|
||||||
test_git_failed=Fehler beim Test des 'git' Kommandos: %v
|
test_git_failed=Fehler beim Test des 'git' Kommandos: %v
|
||||||
sqlite3_not_available=Diese Gitea-Version unterstützt SQLite3 nicht. Bitte lade die offizielle binäre Version von %s herunter (nicht die 'gobuild'-Version).
|
sqlite3_not_available=Diese Gitea-Version unterstützt SQLite3 nicht. Bitte lade die offizielle binäre Version von %s herunter (nicht die „gobuild“-Version).
|
||||||
invalid_db_setting=Datenbankeinstellungen sind ungültig: %v
|
invalid_db_setting=Datenbankeinstellungen sind ungültig: %v
|
||||||
invalid_repo_path=Repository-Verzeichnis ist ungültig: %v
|
invalid_repo_path=Repository-Verzeichnis ist ungültig: %v
|
||||||
run_user_not_match=Der "Ausführen als" Benutzer ist nicht der aktuelle Benutzer: %s -> %s
|
run_user_not_match=Der „Ausführen als“-Benutzername ist nicht der aktuelle Benutzername: %s -> %s
|
||||||
save_config_failed=Fehler beim Speichern der Konfiguration: %v
|
save_config_failed=Fehler beim Speichern der Konfiguration: %v
|
||||||
invalid_admin_setting=Administrator-Konto Einstellungen sind ungültig: %v
|
invalid_admin_setting=Administrator-Konto Einstellungen sind ungültig: %v
|
||||||
install_success=Willkommen! Danke, dass du Gitea gewählt hast. Viel Spaß!
|
install_success=Willkommen! Danke, dass du Gitea gewählt hast. Viel Spaß!
|
||||||
|
|
@ -162,7 +162,7 @@ default_allow_create_organization_popup=Neuen Nutzern das Erstellen von Organisa
|
||||||
default_enable_timetracking=Zeiterfassung standardmäßig aktivieren
|
default_enable_timetracking=Zeiterfassung standardmäßig aktivieren
|
||||||
default_enable_timetracking_popup=Zeiterfassung standardmäßig für neue Repositories aktivieren.
|
default_enable_timetracking_popup=Zeiterfassung standardmäßig für neue Repositories aktivieren.
|
||||||
no_reply_address=Versteckte E-Mail-Domain
|
no_reply_address=Versteckte E-Mail-Domain
|
||||||
no_reply_address_helper=Domain-Namen für Benutzer mit einer versteckten Emailadresse. Zum Beispiel wird der Benutzername "Joe" in Git als "joe@noreply.example.org" protokolliert, wenn die versteckte E-Mail-Domäne "noreply.example.org" festgelegt ist.
|
no_reply_address_helper=Domain-Name für Benutzer mit einer versteckten Emailadresse. Zum Beispiel wird der Benutzername „Joe“ in Git als „joe@noreply.example.org“ protokolliert, wenn die versteckte E-Mail-Domain „noreply.example.org“ festgelegt ist.
|
||||||
|
|
||||||
[home]
|
[home]
|
||||||
uname_holder=E-Mail-Adresse oder Benutzername
|
uname_holder=E-Mail-Adresse oder Benutzername
|
||||||
|
|
@ -213,7 +213,7 @@ send_reset_mail=E-Mail zum Passwort-zurücksetzen erneut verschicken
|
||||||
reset_password=Passwort zurücksetzen
|
reset_password=Passwort zurücksetzen
|
||||||
invalid_code=Dein Bestätigungs-Code ist ungültig oder abgelaufen.
|
invalid_code=Dein Bestätigungs-Code ist ungültig oder abgelaufen.
|
||||||
reset_password_helper=Passwort zurückzusetzen
|
reset_password_helper=Passwort zurückzusetzen
|
||||||
password_too_short=Das Passwort muss mindenstens %d Zeichen lang sein.
|
password_too_short=Das Passwort muss mindestens %d Zeichen lang sein.
|
||||||
non_local_account=Benutzer, die nicht von Gitea verwaltet werden können ihre Passwörter nicht über das Web Interface ändern.
|
non_local_account=Benutzer, die nicht von Gitea verwaltet werden können ihre Passwörter nicht über das Web Interface ändern.
|
||||||
verify=Verifizieren
|
verify=Verifizieren
|
||||||
scratch_code=Einmalpasswort
|
scratch_code=Einmalpasswort
|
||||||
|
|
@ -225,9 +225,9 @@ login_userpass=Anmelden
|
||||||
login_openid=OpenID
|
login_openid=OpenID
|
||||||
openid_connect_submit=Verbinden
|
openid_connect_submit=Verbinden
|
||||||
openid_connect_title=Mit bestehendem Konto verbinden
|
openid_connect_title=Mit bestehendem Konto verbinden
|
||||||
openid_connect_desc=Die gewählte OpenID URI ist unbekannt. Ordne sie hier einem neuen Account zu.
|
openid_connect_desc=Die gewählte OpenID-URI ist unbekannt. Ordne sie hier einem neuen Account zu.
|
||||||
openid_register_title=Neues Konto einrichten
|
openid_register_title=Neues Konto einrichten
|
||||||
openid_register_desc=Die gewählte OpenID URI ist unbekannt. Ordne sie hier einem neuen Account zu.
|
openid_register_desc=Die gewählte OpenID-URI ist unbekannt. Ordne sie hier einem neuen Account zu.
|
||||||
openid_signin_desc=Gib deine OpenID-URI ein. Zum Beispiel: https://anne.me, bob.openid.org.cn oder gnusocial.net/carry.
|
openid_signin_desc=Gib deine OpenID-URI ein. Zum Beispiel: https://anne.me, bob.openid.org.cn oder gnusocial.net/carry.
|
||||||
disable_forgot_password_mail=Das Zurücksetzen von Passwörtern wurde deaktiviert. Bitte wende dich an den Administrator.
|
disable_forgot_password_mail=Das Zurücksetzen von Passwörtern wurde deaktiviert. Bitte wende dich an den Administrator.
|
||||||
|
|
||||||
|
|
@ -264,8 +264,8 @@ TreeName=Dateipfad
|
||||||
Content=Inhalt
|
Content=Inhalt
|
||||||
|
|
||||||
require_error=` darf nicht leer sein.`
|
require_error=` darf nicht leer sein.`
|
||||||
alpha_dash_error=` sollte nur Buchstaben, Zahlen, Bindestriche ('-') und Unterstriche ('_') enthalten`
|
alpha_dash_error=` sollte nur Buchstaben, Zahlen, Bindestriche („-“) und Unterstriche („_“) enthalten.`
|
||||||
alpha_dash_dot_error=` sollte nur Buchstaben, Zahlen, Bindestriche ('-'), Unterstriche ('_') und Punkte ('.') enthalten`
|
alpha_dash_dot_error=` sollte nur Buchstaben, Zahlen, Bindestriche („-“), Unterstriche („_“) und Punkte („.“) enthalten.`
|
||||||
git_ref_name_error=` muss ein wohlgeformter Git-Referenzname sein.`
|
git_ref_name_error=` muss ein wohlgeformter Git-Referenzname sein.`
|
||||||
size_error=` muss die Größe %s haben.`
|
size_error=` muss die Größe %s haben.`
|
||||||
min_size_error=` muss mindestens %s Zeichen enthalten.`
|
min_size_error=` muss mindestens %s Zeichen enthalten.`
|
||||||
|
|
@ -283,13 +283,13 @@ org_name_been_taken=Der Organisationsname ist bereits vergeben.
|
||||||
team_name_been_taken=Der Teamname ist bereits vergeben.
|
team_name_been_taken=Der Teamname ist bereits vergeben.
|
||||||
team_no_units_error=Das Team muss auf mindestens einen Bereich Zugriff haben.
|
team_no_units_error=Das Team muss auf mindestens einen Bereich Zugriff haben.
|
||||||
email_been_used=Die E-Mail-Adresse wird bereits verwendet.
|
email_been_used=Die E-Mail-Adresse wird bereits verwendet.
|
||||||
openid_been_used=Die OpenID-Adresse "%s" wird bereits verwendet.
|
openid_been_used=Die OpenID-Adresse „%s“ wird bereits verwendet.
|
||||||
username_password_incorrect=Benutzername oder Passwort ist falsch.
|
username_password_incorrect=Benutzername oder Passwort ist falsch.
|
||||||
enterred_invalid_repo_name=Der eingegebenen Repository-Name ist falsch.
|
enterred_invalid_repo_name=Der eingegebenen Repository-Name ist falsch.
|
||||||
enterred_invalid_owner_name=Der Name des neuen Besitzers ist invalid.
|
enterred_invalid_owner_name=Der Name des neuen Besitzers ist ungültig.
|
||||||
enterred_invalid_password=Das eingegebene Passwort ist falsch.
|
enterred_invalid_password=Das eingegebene Passwort ist falsch.
|
||||||
user_not_exist=Dieser Benutzer ist nicht vorhanden.
|
user_not_exist=Dieser Benutzer ist nicht vorhanden.
|
||||||
last_org_owner=Du kannst den letzten Benutzer nicht aus dem "Besitzer"-Team entferenen. Es muss mindestens ein Besitzer in einer Organisation geben.
|
last_org_owner=Du kannst den letzten Benutzer nicht aus dem „Besitzer“-Team entfernen. Es muss mindestens einen Besitzer in einer Organisation geben.
|
||||||
cannot_add_org_to_team=Eine Organisation kann nicht als Teammitglied hinzugefügt werden.
|
cannot_add_org_to_team=Eine Organisation kann nicht als Teammitglied hinzugefügt werden.
|
||||||
|
|
||||||
invalid_ssh_key=Dein SSH-Key kann nicht überprüft werden: %s
|
invalid_ssh_key=Dein SSH-Key kann nicht überprüft werden: %s
|
||||||
|
|
@ -349,7 +349,7 @@ continue=Weiter
|
||||||
cancel=Abbrechen
|
cancel=Abbrechen
|
||||||
language=Sprache
|
language=Sprache
|
||||||
|
|
||||||
lookup_avatar_by_mail=Avatar anhand der E-Mail-Addresse suchen
|
lookup_avatar_by_mail=Profilbild anhand der E-Mail-Addresse suchen
|
||||||
federated_avatar_lookup=Suche nach föderierten Profilbildern
|
federated_avatar_lookup=Suche nach föderierten Profilbildern
|
||||||
enable_custom_avatar=Benutzerdefiniertes Profilbild benutzen
|
enable_custom_avatar=Benutzerdefiniertes Profilbild benutzen
|
||||||
choose_new_avatar=Neues Profilbild auswählen
|
choose_new_avatar=Neues Profilbild auswählen
|
||||||
|
|
@ -364,7 +364,7 @@ new_password=Neues Passwort
|
||||||
retype_new_password=Neues Passwort erneut eingeben
|
retype_new_password=Neues Passwort erneut eingeben
|
||||||
password_incorrect=Das aktuelle Passwort ist falsch.
|
password_incorrect=Das aktuelle Passwort ist falsch.
|
||||||
change_password_success=Dein Passwort wurde aktualisiert. Bitte verwende dieses beim nächsten Einloggen.
|
change_password_success=Dein Passwort wurde aktualisiert. Bitte verwende dieses beim nächsten Einloggen.
|
||||||
password_change_disabled=Benutzer, die nicht von Gitea verwaltet werden, können ihr Passwort im Web Interface nicht ändern.
|
password_change_disabled=Benutzer, die nicht von Gitea verwaltet werden, können ihr Passwort im Web-Interface nicht ändern.
|
||||||
|
|
||||||
emails=E-Mail-Adressen
|
emails=E-Mail-Adressen
|
||||||
manage_emails=E-Mail-Adressen verwalten
|
manage_emails=E-Mail-Adressen verwalten
|
||||||
|
|
@ -383,7 +383,7 @@ add_new_email=Neue E-Mail-Adresse hinzufügen
|
||||||
add_new_openid=Neue OpenID-URI hinzufügen
|
add_new_openid=Neue OpenID-URI hinzufügen
|
||||||
add_email=E-Mail-Adresse hinzufügen
|
add_email=E-Mail-Adresse hinzufügen
|
||||||
add_openid=OpenID-URI hinzufügen
|
add_openid=OpenID-URI hinzufügen
|
||||||
add_email_confirmation_sent=Eine Bestätigungs-E-Mail wurde an '%s' gesendet. Bitte überprüfe dein Postfach innerhalb der nächsten %s, um die E-Mail-Adresse zu bestätigen.
|
add_email_confirmation_sent=Eine Bestätigungs-E-Mail wurde an „%s“ gesendet. Bitte überprüfe dein Postfach innerhalb der nächsten %s, um die E-Mail-Adresse zu bestätigen.
|
||||||
add_email_success=Die neue E-Mail-Addresse wurde hinzugefügt.
|
add_email_success=Die neue E-Mail-Addresse wurde hinzugefügt.
|
||||||
add_openid_success=Die neue OpenID-Adresse wurde hinzugefügt.
|
add_openid_success=Die neue OpenID-Adresse wurde hinzugefügt.
|
||||||
keep_email_private=E-Mail-Adresse verbergen
|
keep_email_private=E-Mail-Adresse verbergen
|
||||||
|
|
@ -394,8 +394,8 @@ manage_ssh_keys=SSH-Schlüssel verwalten
|
||||||
manage_gpg_keys=GPG-Schlüssel verwalten
|
manage_gpg_keys=GPG-Schlüssel verwalten
|
||||||
add_key=Schlüssel hinzufügen
|
add_key=Schlüssel hinzufügen
|
||||||
ssh_desc=Diese öffentlichen SSH-Keys sind mit deinem Account verbunden. Der dazugehörigen privaten SSH-Keys geben dir vollen Zugriff auf deine Repositories.
|
ssh_desc=Diese öffentlichen SSH-Keys sind mit deinem Account verbunden. Der dazugehörigen privaten SSH-Keys geben dir vollen Zugriff auf deine Repositories.
|
||||||
gpg_desc=Diese öffentlichen GPG-Keys sind mit deinem Account verbunden. Halte die dazugehörigen privaten SSH-Keys geheim, da diese deine Commits signieren.
|
gpg_desc=Diese öffentlichen GPG-Keys sind mit deinem Account verbunden. Halte die dazugehörigen privaten GPG-Keys geheim, da diese deine Commits signieren.
|
||||||
ssh_helper=<strong>Brauchst du Hilfe?</strong> Hier ist Githubs Anleitung zum <a href="%s">Erzeugen von SSH-Schlüsseln</a> oder <a href="%s">Lösen einfacher SSH-Probleme</a>.
|
ssh_helper=<strong>Brauchst du Hilfe?</strong> Hier ist GitHubs Anleitung zum <a href="%s">Erzeugen von SSH-Schlüsseln</a> oder zum <a href="%s">Lösen einfacher SSH-Probleme</a>.
|
||||||
gpg_helper=<strong>Brauchst du Hilfe?</strong> Hier ist GitHubs Anleitung <a href="%s">über GPG</a>.
|
gpg_helper=<strong>Brauchst du Hilfe?</strong> Hier ist GitHubs Anleitung <a href="%s">über GPG</a>.
|
||||||
add_new_key=SSH-Schlüssel hinzufügen
|
add_new_key=SSH-Schlüssel hinzufügen
|
||||||
add_new_gpg_key=GPG-Schlüssel hinzufügen
|
add_new_gpg_key=GPG-Schlüssel hinzufügen
|
||||||
|
|
@ -407,8 +407,8 @@ subkeys=Unterschlüssel
|
||||||
key_id=Schlüssel-ID
|
key_id=Schlüssel-ID
|
||||||
key_name=Schlüsselname
|
key_name=Schlüsselname
|
||||||
key_content=Inhalt
|
key_content=Inhalt
|
||||||
add_key_success=Der SSH-Schlüssel "%s" wurde hinzugefügt.
|
add_key_success=Der SSH-Schlüssel „%s“ wurde hinzugefügt.
|
||||||
add_gpg_key_success=Der GPG-Key "%s" wurde hinzugefügt.
|
add_gpg_key_success=Der GPG-Key „%s“ wurde hinzugefügt.
|
||||||
delete_key=Entfernen
|
delete_key=Entfernen
|
||||||
ssh_key_deletion=SSH-Schlüssel entfernen
|
ssh_key_deletion=SSH-Schlüssel entfernen
|
||||||
gpg_key_deletion=GPG-Schlüssel entfernen
|
gpg_key_deletion=GPG-Schlüssel entfernen
|
||||||
|
|
@ -511,10 +511,10 @@ create_repo=Repository erstellen
|
||||||
default_branch=Standardbranch
|
default_branch=Standardbranch
|
||||||
mirror_prune=Entfernen
|
mirror_prune=Entfernen
|
||||||
mirror_prune_desc=Entferne veraltete remote-tracking Referenzen
|
mirror_prune_desc=Entferne veraltete remote-tracking Referenzen
|
||||||
mirror_interval=Spiegelintervall (gültige Zeiteinheiten sind 'h', 'm', 's')
|
mirror_interval=Spiegelintervall (gültige Zeiteinheiten sind „h“, „m“, „s“)
|
||||||
mirror_interval_invalid=Das Spiegel-Intervall ist ungültig.
|
mirror_interval_invalid=Das Spiegel-Intervall ist ungültig.
|
||||||
mirror_address=Klonen via URL
|
mirror_address=Klonen via URL
|
||||||
mirror_address_desc=Bitte gebe alle benötigten Zugangsdaten in der URL an.
|
mirror_address_desc=Bitte gib alle benötigten Zugangsdaten in der URL an.
|
||||||
mirror_last_synced=Zuletzt synchronisiert
|
mirror_last_synced=Zuletzt synchronisiert
|
||||||
watchers=Beobachter
|
watchers=Beobachter
|
||||||
stargazers=Favorisiert von
|
stargazers=Favorisiert von
|
||||||
|
|
@ -523,7 +523,7 @@ pick_reaction=Wähle eine Reaktion
|
||||||
reactions_more=und %d weitere
|
reactions_more=und %d weitere
|
||||||
|
|
||||||
form.reach_limit_of_creation=Du hast bereits dein Limit von %d Repositories erreicht.
|
form.reach_limit_of_creation=Du hast bereits dein Limit von %d Repositories erreicht.
|
||||||
form.name_reserved=Der Repository-Name '%s' ist reserviert.
|
form.name_reserved=Der Repository-Name „%s“ ist reserviert.
|
||||||
form.name_pattern_not_allowed='%s' ist nicht erlaubt für Repository-Namen.
|
form.name_pattern_not_allowed='%s' ist nicht erlaubt für Repository-Namen.
|
||||||
|
|
||||||
need_auth=Authentifizierung zum Klonen benötigt
|
need_auth=Authentifizierung zum Klonen benötigt
|
||||||
|
|
@ -588,7 +588,7 @@ editor.edit_file=Datei bearbeiten
|
||||||
editor.preview_changes=Vorschau der Änderungen
|
editor.preview_changes=Vorschau der Änderungen
|
||||||
editor.cannot_edit_non_text_files=Binärdateien können nicht im Webinterface bearbeitet werden.
|
editor.cannot_edit_non_text_files=Binärdateien können nicht im Webinterface bearbeitet werden.
|
||||||
editor.edit_this_file=Datei bearbeiten
|
editor.edit_this_file=Datei bearbeiten
|
||||||
editor.must_be_on_a_branch=Du musst dich in einer Branch befinden, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen.
|
editor.must_be_on_a_branch=Du musst dich in einem Branch befinden, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen.
|
||||||
editor.fork_before_edit=Du musst dieses Repository forken, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen.
|
editor.fork_before_edit=Du musst dieses Repository forken, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen.
|
||||||
editor.delete_this_file=Datei löschen
|
editor.delete_this_file=Datei löschen
|
||||||
editor.must_have_write_access=Du benötigst Schreibzugriff, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen.
|
editor.must_have_write_access=Du benötigst Schreibzugriff, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen.
|
||||||
|
|
@ -598,31 +598,31 @@ editor.filename_help=Füge einen Ordner hinzu, indem du seinen Namen und anschli
|
||||||
editor.or=oder
|
editor.or=oder
|
||||||
editor.cancel_lower=Abbrechen
|
editor.cancel_lower=Abbrechen
|
||||||
editor.commit_changes=Änderungen committen
|
editor.commit_changes=Änderungen committen
|
||||||
editor.add_tmpl='%s/<filename>' hinzufügen
|
editor.add_tmpl=„%s/<filename>“ hinzufügen
|
||||||
editor.add='%s' hinzufügen
|
editor.add=„%s“ hinzufügen
|
||||||
editor.update='%s' ändern
|
editor.update=„%s“ ändern
|
||||||
editor.delete='%s' löschen
|
editor.delete=„%s“ löschen
|
||||||
editor.commit_message_desc=Eine ausführlichere (optionale) Beschreibung hinzufügen…
|
editor.commit_message_desc=Eine ausführlichere (optionale) Beschreibung hinzufügen…
|
||||||
editor.commit_directly_to_this_branch=Direkt in die <strong class="branch-name">%s</strong>-Branch einchecken.
|
editor.commit_directly_to_this_branch=Direkt in den Branch „<strong class="branch-name">%s</strong>“ einchecken.
|
||||||
editor.create_new_branch=Einen <strong>neue Branch</strong> für diesen Commit erstellen und einen Pull Request starten.
|
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 Branchname…
|
editor.new_branch_name_desc=Neuer Branchname…
|
||||||
editor.cancel=Abbrechen
|
editor.cancel=Abbrechen
|
||||||
editor.filename_cannot_be_empty=Der Dateiname darf nicht leer sein.
|
editor.filename_cannot_be_empty=Der Dateiname darf nicht leer sein.
|
||||||
editor.branch_already_exists=Branch '%s' existiert bereits in diesem Repository.
|
editor.branch_already_exists=Branch '%s' existiert bereits in diesem Repository.
|
||||||
editor.directory_is_a_file=Der Verzeichnisname '%s' wird bereits als Dateiname in diesem Repository verwendet.
|
editor.directory_is_a_file=Der Verzeichnisname „%s“ wird bereits als Dateiname in diesem Repository verwendet.
|
||||||
editor.file_is_a_symlink='%s' ist ein symolischer Link. Symbolische Links können mit dem Web Editor nicht bearbeitet werden.
|
editor.file_is_a_symlink='%s' ist ein symolischer Link. Symbolische Links können mit dem Web Editor nicht bearbeitet werden.
|
||||||
editor.filename_is_a_directory=Der Dateiname '%s' wird bereits als Verzeichnisname in diesem Repository verwendet.
|
editor.filename_is_a_directory=Der Dateiname „%s“ wird bereits als Verzeichnisname in diesem Repository verwendet.
|
||||||
editor.file_editing_no_longer_exists=Die bearbeitete Datei '%s' existiert nicht mehr in diesem Repository.
|
editor.file_editing_no_longer_exists=Die bearbeitete Datei „%s“ existiert nicht mehr in diesem Repository.
|
||||||
editor.file_changed_while_editing=Der Inhalt der Datei hat sich seit dem Beginn der Bearbeitung geändert. <a target="_blank" rel="noopener" href="%s">Hier klicken</a> um die Änderungen anzusehen, oder <strong>Änderungen erneut comitten</strong> um sie zu überschreiben.
|
editor.file_changed_while_editing=Der Inhalt der Datei hat sich seit dem Beginn der Bearbeitung geändert. <a target="_blank" rel="noopener" href="%s">Hier klicken</a>, um die Änderungen anzusehen, oder <strong>Änderungen erneut comitten</strong>, um sie zu überschreiben.
|
||||||
editor.file_already_exists=Eine Datei mit dem Namen '%s' ist bereits in diesem Repository vorhanden.
|
editor.file_already_exists=Eine Datei mit dem Namen „%s“ ist bereits in diesem Repository vorhanden.
|
||||||
editor.no_changes_to_show=Keine Änderungen vorhanden.
|
editor.no_changes_to_show=Keine Änderungen vorhanden.
|
||||||
editor.fail_to_update_file=Fehler beim Ändern/Erstellen der Datei '%s'. Fehler: %v
|
editor.fail_to_update_file=Fehler beim Ändern/Erstellen der Datei '%s'. Fehler: %v
|
||||||
editor.add_subdir=Verzeichnis erstellen…
|
editor.add_subdir=Verzeichnis erstellen…
|
||||||
editor.unable_to_upload_files=Fehler beim Hochladen der Dateien nach '%s'. Fehler: %v
|
editor.unable_to_upload_files=Fehler beim Hochladen der Dateien nach „%s“. Fehler: %v
|
||||||
editor.upload_files_to_dir=Dateien hochladen nach '%s'
|
editor.upload_files_to_dir=Dateien hochladen nach '%s'
|
||||||
editor.cannot_commit_to_protected_branch=Commit in den geschützten Branch '%s' ist nicht möglich.
|
editor.cannot_commit_to_protected_branch=Commit in den geschützten Branch „%s“ ist nicht möglich.
|
||||||
|
|
||||||
commits.desc=Durchsuche die Quellcode Änderungshistorie.
|
commits.desc=Durchsuche die Quellcode-Änderungshistorie.
|
||||||
commits.commits=Commits
|
commits.commits=Commits
|
||||||
commits.search=Commits durchsuchen…
|
commits.search=Commits durchsuchen…
|
||||||
commits.find=Suchen
|
commits.find=Suchen
|
||||||
|
|
@ -633,7 +633,7 @@ commits.date=Datum
|
||||||
commits.older=Älter
|
commits.older=Älter
|
||||||
commits.newer=Neuer
|
commits.newer=Neuer
|
||||||
commits.signed_by=Signiert von
|
commits.signed_by=Signiert von
|
||||||
commits.gpg_key_id=GPG Schlüssel-ID
|
commits.gpg_key_id=GPG-Schlüssel-ID
|
||||||
|
|
||||||
ext_issues=Externe Issues
|
ext_issues=Externe Issues
|
||||||
ext_issues.desc=Link zu externem Issuetracker.
|
ext_issues.desc=Link zu externem Issuetracker.
|
||||||
|
|
@ -658,7 +658,7 @@ issues.new_label_placeholder=Labelname
|
||||||
issues.new_label_desc_placeholder=Beschreibung
|
issues.new_label_desc_placeholder=Beschreibung
|
||||||
issues.create_label=Label erstellen
|
issues.create_label=Label erstellen
|
||||||
issues.label_templates.title=Lade vordefinierte Label
|
issues.label_templates.title=Lade vordefinierte Label
|
||||||
issues.label_templates.info=Es existieren noch keine Labels. Erstelle ein neues Label ("Neues Label") oder verwende das Standard Label-Set:
|
issues.label_templates.info=Es existieren noch keine Label. Erstelle ein neues Label („Neues Label“) oder verwende das Standard-Label-Set:
|
||||||
issues.label_templates.helper=Wähle ein Label
|
issues.label_templates.helper=Wähle ein Label
|
||||||
issues.label_templates.use=Label-Set verwenden
|
issues.label_templates.use=Label-Set verwenden
|
||||||
issues.label_templates.fail_to_load_file=Fehler beim Laden der Label Template Datei '%s': %v
|
issues.label_templates.fail_to_load_file=Fehler beim Laden der Label Template Datei '%s': %v
|
||||||
|
|
@ -676,7 +676,7 @@ issues.delete_branch_at=`löschte die Branch <b>%s</b> %s`
|
||||||
issues.open_tab=%d offen
|
issues.open_tab=%d offen
|
||||||
issues.close_tab=%d geschlossen
|
issues.close_tab=%d geschlossen
|
||||||
issues.filter_label=Label
|
issues.filter_label=Label
|
||||||
issues.filter_label_no_select=Alle Labels
|
issues.filter_label_no_select=Alle Label
|
||||||
issues.filter_milestone=Meilenstein
|
issues.filter_milestone=Meilenstein
|
||||||
issues.filter_milestone_no_select=Alle Meilensteine
|
issues.filter_milestone_no_select=Alle Meilensteine
|
||||||
issues.filter_assignee=Zuständig
|
issues.filter_assignee=Zuständig
|
||||||
|
|
@ -768,10 +768,10 @@ issues.cancel_tracking_history=hat die Zeiterfassung %s abgebrochen
|
||||||
issues.time_spent_total=Zeitaufwand insgesamt
|
issues.time_spent_total=Zeitaufwand insgesamt
|
||||||
issues.time_spent_from_all_authors=`Aufgewendete Zeit: %s`
|
issues.time_spent_from_all_authors=`Aufgewendete Zeit: %s`
|
||||||
issues.due_date=Fällig am
|
issues.due_date=Fällig am
|
||||||
issues.invalid_due_date_format=Das Fälligkeitsdatum muss das Format 'JJJJ-MM-TT' haben.
|
issues.invalid_due_date_format=Das Fälligkeitsdatum muss das Format „JJJJ-MM-TT“ haben.
|
||||||
issues.error_modifying_due_date=Fehler beim Ändern des Fälligkeitsdatums.
|
issues.error_modifying_due_date=Fehler beim Ändern des Fälligkeitsdatums.
|
||||||
issues.error_removing_due_date=Fehler beim Entfernen des Fälligkeitsdatums.
|
issues.error_removing_due_date=Fehler beim Entfernen des Fälligkeitsdatums.
|
||||||
issues.due_date_form=jjjj-mm-tt
|
issues.due_date_form=JJJJ-MM-TT
|
||||||
issues.due_date_form_add=Fälligkeitsdatum hinzufügen
|
issues.due_date_form_add=Fälligkeitsdatum hinzufügen
|
||||||
issues.due_date_form_update=Fälligkeitsdatum ändern
|
issues.due_date_form_update=Fälligkeitsdatum ändern
|
||||||
issues.due_date_form_remove=Fälligkeitsdatum löschen
|
issues.due_date_form_remove=Fälligkeitsdatum löschen
|
||||||
|
|
@ -787,7 +787,7 @@ pulls.new=Neuer Pull-Request
|
||||||
pulls.compare_changes=Neuer Pull-Request
|
pulls.compare_changes=Neuer Pull-Request
|
||||||
pulls.compare_changes_desc=Wähle die Ziel- und Quellbranch aus.
|
pulls.compare_changes_desc=Wähle die Ziel- und Quellbranch aus.
|
||||||
pulls.compare_base=Ziel
|
pulls.compare_base=Ziel
|
||||||
pulls.compare_compare=pull von
|
pulls.compare_compare=pullen von
|
||||||
pulls.filter_branch=Branch filtern
|
pulls.filter_branch=Branch filtern
|
||||||
pulls.no_results=Keine Ergebnisse verfügbar.
|
pulls.no_results=Keine Ergebnisse verfügbar.
|
||||||
pulls.nothing_to_compare=Diese Branches sind identisch. Es muss kein Pull-Request erstellt werden.
|
pulls.nothing_to_compare=Diese Branches sind identisch. Es muss kein Pull-Request erstellt werden.
|
||||||
|
|
@ -827,13 +827,13 @@ milestones.title=Titel
|
||||||
milestones.desc=Beschreibung
|
milestones.desc=Beschreibung
|
||||||
milestones.due_date=Fälligkeitsdatum (optional)
|
milestones.due_date=Fälligkeitsdatum (optional)
|
||||||
milestones.clear=Feld leeren
|
milestones.clear=Feld leeren
|
||||||
milestones.invalid_due_date_format=Das Fälligkeitsdatum muss das Format 'JJJJ-MM-TT' haben.
|
milestones.invalid_due_date_format=Das Fälligkeitsdatum muss das Format „JJJJ-MM-TT“ haben.
|
||||||
milestones.create_success=Der Meilenstein '%s' wurde erstellt.
|
milestones.create_success=Der Meilenstein „%s“ wurde erstellt.
|
||||||
milestones.edit=Meilenstein bearbeiten
|
milestones.edit=Meilenstein bearbeiten
|
||||||
milestones.edit_subheader=Benutze Meilensteine, um Issues zu organisieren und den Fortschritt darzustellen.
|
milestones.edit_subheader=Benutze Meilensteine, um Issues zu organisieren und den Fortschritt darzustellen.
|
||||||
milestones.cancel=Abbrechen
|
milestones.cancel=Abbrechen
|
||||||
milestones.modify=Meilenstein bearbeiten
|
milestones.modify=Meilenstein bearbeiten
|
||||||
milestones.edit_success=Die Änderungen am Meilenstein "%s" wurden gespeichert.
|
milestones.edit_success=Die Änderungen am Meilenstein „%s“ wurden gespeichert.
|
||||||
milestones.deletion=Meilenstein löschen
|
milestones.deletion=Meilenstein löschen
|
||||||
milestones.deletion_desc=Das Löschen des Meilensteins entfernt ihn von allen Issues. Fortfahren?
|
milestones.deletion_desc=Das Löschen des Meilensteins entfernt ihn von allen Issues. Fortfahren?
|
||||||
milestones.deletion_success=Der Meilenstein wurde gelöscht.
|
milestones.deletion_success=Der Meilenstein wurde gelöscht.
|
||||||
|
|
@ -849,7 +849,7 @@ ext_wiki.desc=Verweis auf externes Wiki.
|
||||||
|
|
||||||
wiki=Wiki
|
wiki=Wiki
|
||||||
wiki.welcome=Willkommen im Wiki.
|
wiki.welcome=Willkommen im Wiki.
|
||||||
wiki.welcome_desc=Im Wiki kannst Dokumentation schreiben und mit Mitarbeitern teilen.
|
wiki.welcome_desc=Im Wiki kannst du Dokumentation schreiben und sie mit Mitarbeitern teilen.
|
||||||
wiki.desc=Schreibe und teile Dokumentation mit Mitarbeitern.
|
wiki.desc=Schreibe und teile Dokumentation mit Mitarbeitern.
|
||||||
wiki.create_first_page=Erstelle die erste Seite
|
wiki.create_first_page=Erstelle die erste Seite
|
||||||
wiki.page=Seite
|
wiki.page=Seite
|
||||||
|
|
@ -861,9 +861,9 @@ wiki.last_commit_info=%s hat diese Seite bearbeitet %s
|
||||||
wiki.edit_page_button=Bearbeiten
|
wiki.edit_page_button=Bearbeiten
|
||||||
wiki.new_page_button=Neue Seite
|
wiki.new_page_button=Neue Seite
|
||||||
wiki.delete_page_button=Seite löschen
|
wiki.delete_page_button=Seite löschen
|
||||||
wiki.delete_page_notice_1=Das Löschen der Wiki-Seite '%s' kann nicht Rückgängig gemacht werden. Fortfahren?
|
wiki.delete_page_notice_1=Das Löschen der Wiki-Seite „%s“ kann nicht rückgängig gemacht werden. Fortfahren?
|
||||||
wiki.page_already_exists=Eine Wiki-Seite mit dem gleichen Namen existiert bereits.
|
wiki.page_already_exists=Eine Wiki-Seite mit dem gleichen Namen existiert bereits.
|
||||||
wiki.reserved_page=Der Wiki-Seitenname "%s" ist reserviert.
|
wiki.reserved_page=Der Wiki-Seitenname „%s“ ist reserviert.
|
||||||
wiki.pages=Seiten
|
wiki.pages=Seiten
|
||||||
wiki.last_updated=Zuletzt aktualisiert %s
|
wiki.last_updated=Zuletzt aktualisiert %s
|
||||||
|
|
||||||
|
|
@ -911,7 +911,7 @@ activity.published_release_label=Veröffentlicht
|
||||||
|
|
||||||
search=Suchen
|
search=Suchen
|
||||||
search.search_repo=Repository durchsuchen
|
search.search_repo=Repository durchsuchen
|
||||||
search.results=Suchergebnisse für "%s" in <a href="%s"> %s</a>
|
search.results=Suchergebnisse für „%s“ in <a href="%s"> %s</a>
|
||||||
|
|
||||||
settings=Einstellungen
|
settings=Einstellungen
|
||||||
settings.desc=In den Einstellungen kannst du die Einstellungen des Repository anpassen
|
settings.desc=In den Einstellungen kannst du die Einstellungen des Repository anpassen
|
||||||
|
|
@ -925,28 +925,28 @@ settings.hooks=Webhooks
|
||||||
settings.githooks=Git-Hooks
|
settings.githooks=Git-Hooks
|
||||||
settings.basic_settings=Grundeinstellungen
|
settings.basic_settings=Grundeinstellungen
|
||||||
settings.mirror_settings=Mirror Einstellungen
|
settings.mirror_settings=Mirror Einstellungen
|
||||||
settings.sync_mirror=Jetzt Synchronisieren
|
settings.sync_mirror=Jetzt synchronisieren
|
||||||
settings.mirror_sync_in_progress=Mirror-Synchronisierung wird zurzeit ausgeführt. Komm in ein paar Minuten zurück.
|
settings.mirror_sync_in_progress=Mirror-Synchronisierung wird zurzeit ausgeführt. Komm in ein paar Minuten zurück.
|
||||||
settings.site=Webseite
|
settings.site=Webseite
|
||||||
settings.update_settings=Einstellungen speichern
|
settings.update_settings=Einstellungen speichern
|
||||||
settings.advanced_settings=Erweiterte Einstellungen
|
settings.advanced_settings=Erweiterte Einstellungen
|
||||||
settings.wiki_desc=Repository Wiki aktivieren
|
settings.wiki_desc=Repository-Wiki aktivieren
|
||||||
settings.use_internal_wiki=Eingebautes Wiki verwenden
|
settings.use_internal_wiki=Eingebautes Wiki verwenden
|
||||||
settings.use_external_wiki=Externes Wiki verwenden
|
settings.use_external_wiki=Externes Wiki verwenden
|
||||||
settings.external_wiki_url=Externe Wiki URL
|
settings.external_wiki_url=Externe Wiki URL
|
||||||
settings.external_wiki_url_error=Die externe Wiki-URL ist ungültig.
|
settings.external_wiki_url_error=Die externe Wiki-URL ist ungültig.
|
||||||
settings.external_wiki_url_desc=Besucher werden auf die externe Wiki-URL weitergeleitet wenn sie auf das Wiki-Tab klicken.
|
settings.external_wiki_url_desc=Besucher werden auf die externe Wiki-URL weitergeleitet, wenn sie auf das Wiki-Tab klicken.
|
||||||
settings.issues_desc=Repository Issue-Tracker aktivieren
|
settings.issues_desc=Repository-Issue-Tracker aktivieren
|
||||||
settings.use_internal_issue_tracker=Integrierten Issue-Tracker verwenden
|
settings.use_internal_issue_tracker=Integrierten Issue-Tracker verwenden
|
||||||
settings.use_external_issue_tracker=Externen Issue-Tracker verwenden
|
settings.use_external_issue_tracker=Externen Issue-Tracker verwenden
|
||||||
settings.external_tracker_url=URL eines externen Issue Trackers
|
settings.external_tracker_url=URL eines externen Issue Trackers
|
||||||
settings.external_tracker_url_error=Die URL des externen Issue-Trackers ist ungültig.
|
settings.external_tracker_url_error=Die URL des externen Issue-Trackers ist ungültig.
|
||||||
settings.external_tracker_url_desc=Besucher werden auf die externe Issue-Tracker-URL weitergeleitet wenn sie auf das Issues-Tab klicken.
|
settings.external_tracker_url_desc=Besucher werden auf die externe Issue-Tracker-URL weitergeleitet, wenn sie auf das Issues-Tab klicken.
|
||||||
settings.tracker_url_format=URL-Format des externen Issue-Systems
|
settings.tracker_url_format=URL-Format des externen Issue-Systems
|
||||||
settings.tracker_issue_style=Namenskonvention des externen Issue-Trackers
|
settings.tracker_issue_style=Namenskonvention des externen Issue-Trackers
|
||||||
settings.tracker_issue_style.numeric=Numerisch
|
settings.tracker_issue_style.numeric=Numerisch
|
||||||
settings.tracker_issue_style.alphanumeric=Alphanumerisch
|
settings.tracker_issue_style.alphanumeric=Alphanumerisch
|
||||||
settings.tracker_url_format_desc=Du kannst die Platzhalter <code>{user}</code>, <code>{repo}</code>, <code>{index}</code> für den Benutzernamen, den Namen des Repositories und die Issue-Nummer verwenden.
|
settings.tracker_url_format_desc=Du kannst die Platzhalter <code>{user}</code>, <code>{repo}</code>, <code>{index}</code> für den Benutzernamen, den Namen des Repositorys und die Issue-Nummer verwenden.
|
||||||
settings.enable_timetracker=Zeiterfassung aktivieren
|
settings.enable_timetracker=Zeiterfassung aktivieren
|
||||||
settings.allow_only_contributors_to_track_time=Nur Mitarbeitern erlauben, die Zeiterfassung zu nutzen
|
settings.allow_only_contributors_to_track_time=Nur Mitarbeitern erlauben, die Zeiterfassung zu nutzen
|
||||||
settings.pulls_desc=Repository-Pull-Requests aktivieren
|
settings.pulls_desc=Repository-Pull-Requests aktivieren
|
||||||
|
|
@ -964,22 +964,22 @@ settings.convert_notices_1=Dieser Vorgang wandelt das Mirror-Repository in ein n
|
||||||
settings.convert_confirm=Repository umwandeln
|
settings.convert_confirm=Repository umwandeln
|
||||||
settings.convert_succeed=Das Mirror-Repository wurde erfolgreich in ein normales Repository umgewandelt.
|
settings.convert_succeed=Das Mirror-Repository wurde erfolgreich in ein normales Repository umgewandelt.
|
||||||
settings.transfer=Besitz übertragen
|
settings.transfer=Besitz übertragen
|
||||||
settings.transfer_desc=Übertrage dieses Repository auf einen anderen Benutzer oder eine Organisation in der Du Admin-Rechte hast.
|
settings.transfer_desc=Übertrage dieses Repository auf einen anderen Benutzer oder eine Organisation, in der du Admin-Rechte hast.
|
||||||
settings.transfer_notices_1=- Du wirst keinen Zugriff mehr haben, wenn der neue Besitzer ein individueller Benutzer ist.
|
settings.transfer_notices_1=– Du wirst keinen Zugriff mehr haben, wenn der neue Besitzer ein individueller Benutzer ist.
|
||||||
settings.transfer_notices_2=- Du wirst weiterhin Zugriff haben, wenn der neue Besitzer eine Organisation ist und du einer der Besitzer bist.
|
settings.transfer_notices_2=– Du wirst weiterhin Zugriff haben, wenn der neue Besitzer eine Organisation ist und du einer der Besitzer bist.
|
||||||
settings.transfer_form_title=Gib den Repository-Namen zur Bestätigung ein:
|
settings.transfer_form_title=Gib den Repository-Namen zur Bestätigung ein:
|
||||||
settings.wiki_delete=Wiki-Daten löschen
|
settings.wiki_delete=Wiki-Daten löschen
|
||||||
settings.wiki_delete_desc=Das Löschen von Wiki-Daten kann nicht rückgängig gemacht werden. Bitte sei vorsichtig.
|
settings.wiki_delete_desc=Das Löschen von Wiki-Daten kann nicht rückgängig gemacht werden. Bitte sei vorsichtig.
|
||||||
settings.wiki_delete_notices_1=- Dies löscht und deaktiviert das Wiki für %s.
|
settings.wiki_delete_notices_1=– Dies löscht und deaktiviert das Wiki für %s.
|
||||||
settings.confirm_wiki_delete=Wiki-Daten löschen
|
settings.confirm_wiki_delete=Wiki-Daten löschen
|
||||||
settings.wiki_deletion_success=Repository Wiki-Daten wurden gelöscht.
|
settings.wiki_deletion_success=Repository-Wiki-Daten wurden gelöscht.
|
||||||
settings.delete=Dieses Repository löschen
|
settings.delete=Dieses Repository löschen
|
||||||
settings.delete_desc=Wenn dieses Repository gelöscht wurde, gibt es keinen Weg zurück. Bitte sei vorsichtig.
|
settings.delete_desc=Wenn dieses Repository gelöscht wurde, gibt es keinen Weg zurück. Bitte sei vorsichtig.
|
||||||
settings.delete_notices_1=- Diese Operation kann <strong>NICHT</strong> rückgängig gemacht werden.
|
settings.delete_notices_1=- Diese Operation kann <strong>NICHT</strong> rückgängig gemacht werden.
|
||||||
settings.delete_notices_2=- Die Operation wird das <strong>%s</strong>-Repository dauerhaft löschen, inklusive der Dateien, Issues, Kommentare und Zugriffseinstellungen.
|
settings.delete_notices_2=– Die Operation wird das <strong>%s</strong>-Repository dauerhaft löschen, inklusive der Dateien, Issues, Kommentare und Zugriffseinstellungen.
|
||||||
settings.delete_notices_fork_1=- Nach dem Löschen werden alle Forks unabhängig.
|
settings.delete_notices_fork_1=– Forks dieses Repositorys werden nach dem Löschen unabhängig.
|
||||||
settings.deletion_success=Das Repository wurde gelöscht.
|
settings.deletion_success=Das Repository wurde gelöscht.
|
||||||
settings.update_settings_success=Repository Einstellungen wurden aktualisiert.
|
settings.update_settings_success=Repository-Einstellungen wurden aktualisiert.
|
||||||
settings.transfer_owner=Neuer Besitzer
|
settings.transfer_owner=Neuer Besitzer
|
||||||
settings.make_transfer=Transfer durchführen
|
settings.make_transfer=Transfer durchführen
|
||||||
settings.transfer_succeed=Das Repository wurde transferiert.
|
settings.transfer_succeed=Das Repository wurde transferiert.
|
||||||
|
|
@ -994,7 +994,7 @@ settings.search_user_placeholder=Benutzer suchen…
|
||||||
settings.org_not_allowed_to_be_collaborator=Organisationen können nicht als Mitarbeiter hinzugefügt werden.
|
settings.org_not_allowed_to_be_collaborator=Organisationen können nicht als Mitarbeiter hinzugefügt werden.
|
||||||
settings.user_is_org_member=Der Benutzer ist ein Organisationsmitglied und kann nicht als Mitarbeiter hinzugefügt werden.
|
settings.user_is_org_member=Der Benutzer ist ein Organisationsmitglied und kann nicht als Mitarbeiter hinzugefügt werden.
|
||||||
settings.add_webhook=Webhook hinzufügen
|
settings.add_webhook=Webhook hinzufügen
|
||||||
settings.hooks_desc=Webhooks senden bei bestimmten Gitea-Events automatisch HTTP POST-Requets an einen Server. Lies mehr in unserer <a target="_blank" rel="noopener" href="%s">Anleitung zu Webhooks (Englisch)</a>.
|
settings.hooks_desc=Webhooks senden bei bestimmten Gitea-Events automatisch „HTTP POST“-Anfragen an einen Server. Lies mehr in unserer <a target="_blank" rel="noopener" href="%s">Anleitung zu Webhooks (auf Englisch)</a>.
|
||||||
settings.webhook_deletion=Webhook löschen
|
settings.webhook_deletion=Webhook löschen
|
||||||
settings.webhook_deletion_desc=Das Entfernen eines Webhooks löscht seine Einstellungen und Zustellungsverlauf. Fortfahren?
|
settings.webhook_deletion_desc=Das Entfernen eines Webhooks löscht seine Einstellungen und Zustellungsverlauf. Fortfahren?
|
||||||
settings.webhook_deletion_success=Webhook wurde entfernt.
|
settings.webhook_deletion_success=Webhook wurde entfernt.
|
||||||
|
|
@ -1066,18 +1066,18 @@ settings.title=Titel
|
||||||
settings.deploy_key_content=Inhalt
|
settings.deploy_key_content=Inhalt
|
||||||
settings.key_been_used=Ein Deploy-Key mit identischem Inhalt wird bereits verwendet.
|
settings.key_been_used=Ein Deploy-Key mit identischem Inhalt wird bereits verwendet.
|
||||||
settings.key_name_used=Ein Deploy-Key mit diesem Namen existiert bereits.
|
settings.key_name_used=Ein Deploy-Key mit diesem Namen existiert bereits.
|
||||||
settings.add_key_success=Der Deploy-Key '%s' wurde erfolgreich hinzugefügt.
|
settings.add_key_success=Der Deploy-Key „%s“ wurde erfolgreich hinzugefügt.
|
||||||
settings.deploy_key_deletion=Deploy-Key löschen
|
settings.deploy_key_deletion=Deploy-Key löschen
|
||||||
settings.deploy_key_deletion_desc=Nach dem Löschen wird dieser Deploy-Key keinen Zugriff mehr auf dieses Repository haben. Fortfahren?
|
settings.deploy_key_deletion_desc=Nach dem Löschen wird dieser Deploy-Key keinen Zugriff mehr auf dieses Repository haben. Fortfahren?
|
||||||
settings.deploy_key_deletion_success=Der Deploy-Key wurde entfernt.
|
settings.deploy_key_deletion_success=Der Deploy-Key wurde entfernt.
|
||||||
settings.branches=Branches
|
settings.branches=Branches
|
||||||
settings.protected_branch=Branch-Protection
|
settings.protected_branch=Branch-Schutz
|
||||||
settings.protected_branch_can_push=Push erlauben?
|
settings.protected_branch_can_push=Push erlauben?
|
||||||
settings.protected_branch_can_push_yes=Du kannst pushen
|
settings.protected_branch_can_push_yes=Du kannst pushen
|
||||||
settings.protected_branch_can_push_no=Du kannst nicht pushen
|
settings.protected_branch_can_push_no=Du kannst nicht pushen
|
||||||
settings.branch_protection=Branch-Schutz" für Branch '<b>%s</b>'
|
settings.branch_protection=Branch-Schutz für Branch „<b>%s</b>“
|
||||||
settings.protect_this_branch=Brach-Schutz aktivieren
|
settings.protect_this_branch=Brach-Schutz aktivieren
|
||||||
settings.protect_this_branch_desc=Verhindere Löschen und deaktiviere Git force push auf diese Branch.
|
settings.protect_this_branch_desc=Verhindere Löschen und deaktiviere das sog. „force pushing” von Git auf diesen Branch.
|
||||||
settings.protect_whitelist_committers=Push-Whitelist aktivieren
|
settings.protect_whitelist_committers=Push-Whitelist aktivieren
|
||||||
settings.protect_whitelist_committers_desc=Erlaube Nutzern oder Teams auf der Whitelist Push-Beschränkungen zu umgehen.
|
settings.protect_whitelist_committers_desc=Erlaube Nutzern oder Teams auf der Whitelist Push-Beschränkungen zu umgehen.
|
||||||
settings.protect_whitelist_users=Nutzer, die pushen dürfen:
|
settings.protect_whitelist_users=Nutzer, die pushen dürfen:
|
||||||
|
|
@ -1085,17 +1085,17 @@ settings.protect_whitelist_search_users=Benutzer suchen…
|
||||||
settings.protect_whitelist_teams=Teams, die pushen dürfen:
|
settings.protect_whitelist_teams=Teams, die pushen dürfen:
|
||||||
settings.protect_whitelist_search_teams=Suche nach Teams…
|
settings.protect_whitelist_search_teams=Suche nach Teams…
|
||||||
settings.protect_merge_whitelist_committers=Merge-Whitelist aktivieren
|
settings.protect_merge_whitelist_committers=Merge-Whitelist aktivieren
|
||||||
settings.protect_merge_whitelist_committers_desc=Erlaube Nutzern oder Teams auf der Whitelist Pull-Requests in diese Branch zu mergen.
|
settings.protect_merge_whitelist_committers_desc=Erlaube Nutzern oder Teams auf der Whitelist Pull-Requests in diesen Branch zu mergen.
|
||||||
settings.protect_merge_whitelist_users=Nutzer, die mergen dürfen:
|
settings.protect_merge_whitelist_users=Nutzer, die mergen dürfen:
|
||||||
settings.protect_merge_whitelist_teams=Teams, die mergen dürfen:
|
settings.protect_merge_whitelist_teams=Teams, die mergen dürfen:
|
||||||
settings.add_protected_branch=Schutz aktivieren
|
settings.add_protected_branch=Schutz aktivieren
|
||||||
settings.delete_protected_branch=Schutz deaktivieren
|
settings.delete_protected_branch=Schutz deaktivieren
|
||||||
settings.update_protect_branch_success=Branch-protection für die Branch '%s' wurde geändert.
|
settings.update_protect_branch_success=Branch-Schutz für den Branch „%s“ wurde geändert.
|
||||||
settings.remove_protected_branch_success=Branch-protection für die Branch '%s' wurde deaktiviert.
|
settings.remove_protected_branch_success=Branch-Schutz für den Branch „%s“ wurde deaktiviert.
|
||||||
settings.protected_branch_deletion=Brach-Schutz deaktivieren
|
settings.protected_branch_deletion=Branch-Schutz deaktivieren
|
||||||
settings.protected_branch_deletion_desc=Wenn du die Branch-Protection deaktivierst, können alle Nutzer mit Schreibrechten auf die Branch pushen. Fortfahren?
|
settings.protected_branch_deletion_desc=Wenn du den Branch-Schutz deaktivierst, können alle Nutzer mit Schreibrechten auf den Branch pushen. Fortfahren?
|
||||||
settings.default_branch_desc=Wähle eine Standardbranch für Pull-Requests und Code-Commits:
|
settings.default_branch_desc=Wähle einen Standardbranch für Pull-Requests und Code-Commits:
|
||||||
settings.choose_branch=Wähle eine Branch…
|
settings.choose_branch=Wähle einen Branch …
|
||||||
settings.no_protected_branch=Es gibt keine geschützten Branches.
|
settings.no_protected_branch=Es gibt keine geschützten Branches.
|
||||||
|
|
||||||
diff.browse_source=Quellcode durchsuchen
|
diff.browse_source=Quellcode durchsuchen
|
||||||
|
|
@ -1131,7 +1131,7 @@ release.write=Schreiben
|
||||||
release.preview=Vorschau
|
release.preview=Vorschau
|
||||||
release.loading=Laden…
|
release.loading=Laden…
|
||||||
release.prerelease_desc=Als Pre-Release kennzeichnen
|
release.prerelease_desc=Als Pre-Release kennzeichnen
|
||||||
release.prerelease_helper=Dieses Release als "ungeeignet für den produktiven Einsatz" markieren.
|
release.prerelease_helper=Dieses Release als „ungeeignet für den produktiven Einsatz“ markieren.
|
||||||
release.cancel=Abbrechen
|
release.cancel=Abbrechen
|
||||||
release.publish=Release veröffentlichen
|
release.publish=Release veröffentlichen
|
||||||
release.save_draft=Entwurf speichern
|
release.save_draft=Entwurf speichern
|
||||||
|
|
@ -1146,27 +1146,29 @@ release.downloads=Downloads
|
||||||
|
|
||||||
branch.name=Branchname
|
branch.name=Branchname
|
||||||
branch.search=Branches durchsuchen
|
branch.search=Branches durchsuchen
|
||||||
branch.already_exists=Eine Branch mit dem Namen '%s' existiert bereits.
|
branch.already_exists=Ein Branch mit dem Namen „%s“ existiert bereits.
|
||||||
branch.delete_head=Löschen
|
branch.delete_head=Löschen
|
||||||
branch.delete=Branch '%s' löschen
|
branch.delete=Branch „%s“ löschen
|
||||||
branch.delete_html=Branch löschen
|
branch.delete_html=Branch löschen
|
||||||
branch.delete_desc=Das Löschen einer Branch ist permanent. Es <strong>KANN NICHT</strong> Rückgängig gemacht werden. Fortfahren?
|
branch.delete_desc=Das Löschen eines Branches ist permanent. Es <strong>KANN NICHT</strong> rückgängig gemacht werden. Fortfahren?
|
||||||
branch.deletion_success=Branch '%s' wurde gelöscht.
|
branch.deletion_success=Branch „%s“ wurde gelöscht.
|
||||||
branch.deletion_failed=Branch '%s' konnte nicht gelöscht werden.
|
branch.deletion_failed=Branch „%s“ konnte nicht gelöscht werden.
|
||||||
branch.delete_branch_has_new_commits=Die Branch '%s' kann nicht gelöscht weden, da seit dem letzten Merge neue Commits hinzugefügt wurden.
|
branch.delete_branch_has_new_commits=Der Branch „%s“ kann nicht gelöscht weden, da seit dem letzten Merge neue Commits hinzugefügt wurden.
|
||||||
branch.create_branch=Erstelle Branch <strong>%s</strong>
|
branch.create_branch=Erstelle Branch <strong>%s</strong>
|
||||||
branch.create_from=von '%s'
|
branch.create_from=von '%s'
|
||||||
branch.create_success=Branch '%s' wurde erstellt.
|
branch.create_success=Branch „%s“ wurde erstellt.
|
||||||
branch.branch_already_exists=Branch '%s' existiert bereits in diesem Repository.
|
branch.branch_already_exists=Branch '%s' existiert bereits in diesem Repository.
|
||||||
branch.branch_name_conflict=Der Branch-Name '%s' steht in Konflikt mit der bestehendem Branch '%s'.
|
branch.branch_name_conflict=Der Branch-Name „%s“ steht in Konflikt mit dem bestehenden Branch „%s“.
|
||||||
branch.tag_collision=Branch '%s' kann nicht erstellt werden, da in diesem Repository bereits ein Tag mit dem selben Namen existiert.
|
branch.tag_collision=Branch „%s“ kann nicht erstellt werden, da in diesem Repository bereits ein Tag mit dem selben Namen existiert.
|
||||||
branch.deleted_by=Von %s gelöscht
|
branch.deleted_by=Von %s gelöscht
|
||||||
branch.restore_success=Branch '%s' wurde wiederhergestellt.
|
branch.restore_success=Branch „%s“ wurde wiederhergestellt.
|
||||||
branch.restore_failed=Wiederherstellung der Branch '%s' fehlgeschlagen.
|
branch.restore_failed=Wiederherstellung des Branches „%s“ fehlgeschlagen.
|
||||||
branch.protected_deletion_failed=Branch '%s' ist geschützt und kann nicht gelöscht werden.
|
branch.protected_deletion_failed=Branch „%s“ ist geschützt und kann nicht gelöscht werden.
|
||||||
|
|
||||||
topic.manage_topics=Themen verwalten
|
topic.manage_topics=Themen verwalten
|
||||||
topic.done=Fertig
|
topic.done=Fertig
|
||||||
|
topic.count_prompt=Du kannst nicht mehr als 25 Themen auswählen
|
||||||
|
topic.format_prompt=Themen müssen mit einem Buchstaben oder einer Zahl beginnen. Sie können Bindestriche (-) enthalten und dürfen nicht länger als 35 Zeichen sein
|
||||||
|
|
||||||
[org]
|
[org]
|
||||||
org_name_holder=Name der Organisation
|
org_name_holder=Name der Organisation
|
||||||
|
|
@ -1188,9 +1190,9 @@ team_desc_helper=Beschreibe den Zweck oder die Rolle des Teams.
|
||||||
team_permission_desc=Berechtigungen
|
team_permission_desc=Berechtigungen
|
||||||
team_unit_desc=Zugriff auf Repositorybereiche erlauben
|
team_unit_desc=Zugriff auf Repositorybereiche erlauben
|
||||||
|
|
||||||
form.name_reserved=Der Organisationsname '%s' ist reserviert.
|
form.name_reserved=Der Organisationsname „%s“ ist reserviert.
|
||||||
form.name_pattern_not_allowed=Das Muster '%s' ist in Organisationsnamen nicht erlaubt.
|
form.name_pattern_not_allowed=Das Muster „%s“ ist in Organisationsnamen nicht erlaubt.
|
||||||
form.create_org_not_allowed=Du bist nicht berechtigt eine Organisation zu erstellen.
|
form.create_org_not_allowed=Du bist nicht berechtigt, eine Organisation zu erstellen.
|
||||||
|
|
||||||
settings=Einstellungen
|
settings=Einstellungen
|
||||||
settings.options=Organisation
|
settings.options=Organisation
|
||||||
|
|
@ -1229,7 +1231,7 @@ teams.read_access_helper=Mitglieder können Teamrepositories ansehen und klonen.
|
||||||
teams.write_access=Schreibzugriff
|
teams.write_access=Schreibzugriff
|
||||||
teams.write_access_helper=Mitglieder können Teamrepositories ansehen und auf sie pushen.
|
teams.write_access_helper=Mitglieder können Teamrepositories ansehen und auf sie pushen.
|
||||||
teams.admin_access=Administratorzugang
|
teams.admin_access=Administratorzugang
|
||||||
teams.admin_access_helper=Mitglieder können auf Team Repositories "pushen", von ihnen "pullen" und Mitarbeiter hinzufügen.
|
teams.admin_access_helper=Mitglieder können auf Team-Repositorys pushen, von ihnen pullen und Mitarbeiter hinzufügen.
|
||||||
teams.no_desc=Dieses Team hat keine Beschreibung
|
teams.no_desc=Dieses Team hat keine Beschreibung
|
||||||
teams.settings=Einstellungen
|
teams.settings=Einstellungen
|
||||||
teams.owners_permission_desc=Besitzer haben vollen Zugriff auf <strong>alle Repositories</strong> und <strong>Admin-Rechte</strong> für diese Organisation.
|
teams.owners_permission_desc=Besitzer haben vollen Zugriff auf <strong>alle Repositories</strong> und <strong>Admin-Rechte</strong> für diese Organisation.
|
||||||
|
|
@ -1238,7 +1240,7 @@ teams.update_settings=Einstellungen aktualisieren
|
||||||
teams.delete_team=Team löschen
|
teams.delete_team=Team löschen
|
||||||
teams.add_team_member=Teammitglied hinzufügen
|
teams.add_team_member=Teammitglied hinzufügen
|
||||||
teams.delete_team_title=Team löschen
|
teams.delete_team_title=Team löschen
|
||||||
teams.delete_team_desc=Das Löschen eines Teams wiederruft den Repository-Zugriff für seine Mitglieder. Fortfahren?
|
teams.delete_team_desc=Das Löschen eines Teams widerruft den Repository-Zugriff für seine Mitglieder. Fortfahren?
|
||||||
teams.delete_team_success=Das Team wurde gelöscht.
|
teams.delete_team_success=Das Team wurde gelöscht.
|
||||||
teams.read_permission_desc=Dieses Team hat <strong>Lesezugriff</strong>: Mitglieder können Team-Repositories einsehen und klonen.
|
teams.read_permission_desc=Dieses Team hat <strong>Lesezugriff</strong>: Mitglieder können Team-Repositories einsehen und klonen.
|
||||||
teams.write_permission_desc=Dieses Team hat <strong>Schreibzugriff</strong>: Mitglieder können Team-Repositories einsehen und darauf pushen.
|
teams.write_permission_desc=Dieses Team hat <strong>Schreibzugriff</strong>: Mitglieder können Team-Repositories einsehen und darauf pushen.
|
||||||
|
|
@ -1277,12 +1279,12 @@ dashboard.delete_repo_archives=Alle Repository-Archive löschen
|
||||||
dashboard.delete_repo_archives_success=Alle Repository-Archive wurden gelöscht.
|
dashboard.delete_repo_archives_success=Alle Repository-Archive wurden gelöscht.
|
||||||
dashboard.delete_missing_repos=Alle Repository-Datensätze mit verlorenen gegangenen Git-Dateien löschen
|
dashboard.delete_missing_repos=Alle Repository-Datensätze mit verlorenen gegangenen Git-Dateien löschen
|
||||||
dashboard.delete_missing_repos_success=Alle Repository-Datensätze mit verlorenen Git-Dateien wurden gelöscht.
|
dashboard.delete_missing_repos_success=Alle Repository-Datensätze mit verlorenen Git-Dateien wurden gelöscht.
|
||||||
dashboard.git_gc_repos=Garbage Collection auf Repositories ausführen
|
dashboard.git_gc_repos=Garbage-Collection auf Repositories ausführen
|
||||||
dashboard.git_gc_repos_success=Alle Repositories haben Garbage Collection beendet.
|
dashboard.git_gc_repos_success=Alle Repositories haben Garbage-Collection beendet.
|
||||||
dashboard.resync_all_sshkeys='.ssh/authorized_keys'-Datei mit Gitea SSH-Keys neu schreiben. (Wenn Du den eingebauten SSH Server nutzt, musst du das nicht ausführen.)
|
dashboard.resync_all_sshkeys=„.ssh/authorized_keys“-Datei mit Gitea-SSH-Keys neu schreiben. (Wenn Du den eingebauten SSH-Server nutzt, musst du das nicht ausführen.)
|
||||||
dashboard.resync_all_sshkeys_success=Alle von Gitea verwalteten öffentlichen Schlüssel wurden neu geschrieben.
|
dashboard.resync_all_sshkeys_success=Alle von Gitea verwalteten öffentlichen Schlüssel wurden neu geschrieben.
|
||||||
dashboard.resync_all_hooks=Synchronisiere pre-receive, update und post-receive Hooks für alle Repositories.
|
dashboard.resync_all_hooks=Synchronisiere „pre-receive“-, „update“- und „post-receive“-Hooks für alle Repositorys erneut.
|
||||||
dashboard.resync_all_hooks_success=Alle pre-receive, update und post-receive Repository-Hooks wurden synchronisiert.
|
dashboard.resync_all_hooks_success=Alle „pre-receive“-, „update“- und „post-receive“-Repository-Hooks wurden erneut synchronisiert.
|
||||||
dashboard.reinit_missing_repos=Alle Git-Repositories mit Einträgen neu einlesen
|
dashboard.reinit_missing_repos=Alle Git-Repositories mit Einträgen neu einlesen
|
||||||
dashboard.reinit_missing_repos_success=Alle verlorenen Git-Repositories mit existierenden Einträgen wurden erfolgreich aktualisiert.
|
dashboard.reinit_missing_repos_success=Alle verlorenen Git-Repositories mit existierenden Einträgen wurden erfolgreich aktualisiert.
|
||||||
dashboard.sync_external_users=Externe Benutzerdaten synchronisieren
|
dashboard.sync_external_users=Externe Benutzerdaten synchronisieren
|
||||||
|
|
@ -1305,11 +1307,11 @@ dashboard.heap_memory_released=Freigegebener Heap-Memory
|
||||||
dashboard.heap_objects=Heap-Objekte
|
dashboard.heap_objects=Heap-Objekte
|
||||||
dashboard.bootstrap_stack_usage=Bootstrap-Stack-Auslastung
|
dashboard.bootstrap_stack_usage=Bootstrap-Stack-Auslastung
|
||||||
dashboard.stack_memory_obtained=Erhaltener Stack-Memory
|
dashboard.stack_memory_obtained=Erhaltener Stack-Memory
|
||||||
dashboard.mspan_structures_usage=MSpan-Structures Auslastung
|
dashboard.mspan_structures_usage=MSpan-Structures-Auslastung
|
||||||
dashboard.mspan_structures_obtained=MSpan-Structures erhalten
|
dashboard.mspan_structures_obtained=Erhaltene MSpan-Structures
|
||||||
dashboard.mcache_structures_usage=MCache-Structures Auslastung
|
dashboard.mcache_structures_usage=MCache-Structures-Auslastung
|
||||||
dashboard.mcache_structures_obtained=Erhaltene MCache-Structures
|
dashboard.mcache_structures_obtained=Erhaltene MCache-Structures
|
||||||
dashboard.profiling_bucket_hash_table_obtained=Analysesatz Hashtabellen erhalten
|
dashboard.profiling_bucket_hash_table_obtained=Erhaltene Analysesatz-Hashtabellen
|
||||||
dashboard.gc_metadata_obtained=Erhaltene GC-Metadata
|
dashboard.gc_metadata_obtained=Erhaltene GC-Metadata
|
||||||
dashboard.other_system_allocation_obtained=Andere erhaltene System-Allokationen
|
dashboard.other_system_allocation_obtained=Andere erhaltene System-Allokationen
|
||||||
dashboard.next_gc_recycle=Nächster GC-Zyklus
|
dashboard.next_gc_recycle=Nächster GC-Zyklus
|
||||||
|
|
@ -1342,7 +1344,7 @@ users.max_repo_creation_desc=(Gib -1 ein, um das globale Standardlimit zu verwen
|
||||||
users.is_activated=Account ist aktiviert
|
users.is_activated=Account ist aktiviert
|
||||||
users.prohibit_login=Anmelden deaktivieren
|
users.prohibit_login=Anmelden deaktivieren
|
||||||
users.is_admin=Ist Administrator
|
users.is_admin=Ist Administrator
|
||||||
users.allow_git_hook=Darf "Git Hooks" erstellen
|
users.allow_git_hook=Darf „Git Hooks“ erstellen
|
||||||
users.allow_import_local=Darf lokale Repositories importieren
|
users.allow_import_local=Darf lokale Repositories importieren
|
||||||
users.allow_create_organization=Darf Organisationen erstellen
|
users.allow_create_organization=Darf Organisationen erstellen
|
||||||
users.update_profile=Benutzerkonto aktualisieren
|
users.update_profile=Benutzerkonto aktualisieren
|
||||||
|
|
@ -1384,31 +1386,31 @@ auths.bind_dn=DN binden
|
||||||
auths.bind_password=Passwort binden
|
auths.bind_password=Passwort binden
|
||||||
auths.bind_password_helper=Achtung: Das Passwort wird im Klartext gespeichert. Benutze wenn möglich einen Account mit nur Lesezugriff.
|
auths.bind_password_helper=Achtung: Das Passwort wird im Klartext gespeichert. Benutze wenn möglich einen Account mit nur Lesezugriff.
|
||||||
auths.user_base=Basis für Benutzersuche
|
auths.user_base=Basis für Benutzersuche
|
||||||
auths.user_dn=Benutzer DN
|
auths.user_dn=Benutzer-DN
|
||||||
auths.attribute_username=Benutzername Attribut
|
auths.attribute_username=Benutzernamens-Attribut
|
||||||
auths.attribute_username_placeholder=Leerlassen, um den in Gitea eingegebenen Benutzernamen zu verwenden.
|
auths.attribute_username_placeholder=Leerlassen, um den in Gitea eingegebenen Benutzernamen zu verwenden.
|
||||||
auths.attribute_name=Vornamensattribut
|
auths.attribute_name=Vornamensattribut
|
||||||
auths.attribute_surname=Nachnamensattribut
|
auths.attribute_surname=Nachnamensattribut
|
||||||
auths.attribute_mail=E-Mail Attribut
|
auths.attribute_mail=E-Mail-Attribut
|
||||||
auths.attribute_ssh_public_key=Öffentliches SSH-Schlüssel Attribut
|
auths.attribute_ssh_public_key=Öffentlicher-SSH-Schlüssel-Attribut
|
||||||
auths.attributes_in_bind=Hole Attribute im Bind-Kontext
|
auths.attributes_in_bind=Hole Attribute im Bind-Kontext
|
||||||
auths.use_paged_search=Seitensuche verwenden
|
auths.use_paged_search=Seitensuche verwenden
|
||||||
auths.search_page_size=Seitengröße
|
auths.search_page_size=Seitengröße
|
||||||
auths.filter=Benutzerfilter
|
auths.filter=Benutzerfilter
|
||||||
auths.admin_filter=Admin Filter
|
auths.admin_filter=Admin-Filter
|
||||||
auths.ms_ad_sa=MS AD Suchattribute
|
auths.ms_ad_sa=MS-AD-Suchattribute
|
||||||
auths.smtp_auth=SMTP-Authentifizierungstyp
|
auths.smtp_auth=SMTP-Authentifizierungstyp
|
||||||
auths.smtphost=SMTP-Host
|
auths.smtphost=SMTP-Host
|
||||||
auths.smtpport=SMTP-Port
|
auths.smtpport=SMTP-Port
|
||||||
auths.allowed_domains=Erlaubte Domains
|
auths.allowed_domains=Erlaubte Domains
|
||||||
auths.allowed_domains_helper=Leerlassen, um alle Domains zuzulassen. Trenne mehrere Domänen mit einem Komma (',').
|
auths.allowed_domains_helper=Leerlassen, um alle Domains zuzulassen. Trenne mehrere Domänen mit einem Komma („,“).
|
||||||
auths.enable_tls=TLS-Verschlüsselung aktivieren
|
auths.enable_tls=TLS-Verschlüsselung aktivieren
|
||||||
auths.skip_tls_verify=TLS Verifikation überspringen
|
auths.skip_tls_verify=TLS-Verifikation überspringen
|
||||||
auths.pam_service_name=PAM Dienstname
|
auths.pam_service_name=PAM-Dienstname
|
||||||
auths.oauth2_provider=OAuth2 Anbieter
|
auths.oauth2_provider=OAuth2-Anbieter
|
||||||
auths.oauth2_clientID=Client-ID (Schlüssel)
|
auths.oauth2_clientID=Client-ID (Schlüssel)
|
||||||
auths.oauth2_clientSecret=Client-Secret
|
auths.oauth2_clientSecret=Client-Secret
|
||||||
auths.openIdConnectAutoDiscoveryURL=OpenID Connect Auto Discovery URL
|
auths.openIdConnectAutoDiscoveryURL=OpenID-Connect-Auto-Discovery-URL
|
||||||
auths.oauth2_use_custom_url=Benutzerdefinierte URLs anstelle von Standard-URLs verwenden
|
auths.oauth2_use_custom_url=Benutzerdefinierte URLs anstelle von Standard-URLs verwenden
|
||||||
auths.oauth2_tokenURL=Token-URL
|
auths.oauth2_tokenURL=Token-URL
|
||||||
auths.oauth2_authURL=Authorisierungs-URL
|
auths.oauth2_authURL=Authorisierungs-URL
|
||||||
|
|
@ -1416,48 +1418,48 @@ auths.oauth2_profileURL=Profil-URL
|
||||||
auths.oauth2_emailURL=E-Mail-URL
|
auths.oauth2_emailURL=E-Mail-URL
|
||||||
auths.enable_auto_register=Automatische Registrierung aktivieren
|
auths.enable_auto_register=Automatische Registrierung aktivieren
|
||||||
auths.tips=Tipps
|
auths.tips=Tipps
|
||||||
auths.tips.oauth2.general=OAuth2 Authentifizierung
|
auths.tips.oauth2.general=OAuth2-Authentifizierung
|
||||||
auths.tips.oauth2.general.tip=Beim Registrieren einer neuen OAuth2 Authentifizierung sollte die Callback/Weiterleitungs-URL <host>/user/oauth2/<Authentication Name>/callback sein.
|
auths.tips.oauth2.general.tip=Beim Registrieren einer neuen OAuth2-Authentifizierung sollte die Callback-/Weiterleitungs-URL „<host>/user/oauth2/<Authentication Name>/callback“ sein.
|
||||||
auths.tip.oauth2_provider=OAuth2 Anbieter
|
auths.tip.oauth2_provider=OAuth2-Anbieter
|
||||||
auths.tip.bitbucket=Registriere einen neuen OAuth-Consumer unter https://bitbucket.org/account/user/<dein-benutzername>/oauth-consumers/new und füge die Berechtigung "Account"-"Read" hinzu.
|
auths.tip.bitbucket=Registriere einen neuen OAuth-Consumer unter https://bitbucket.org/account/user/<dein-benutzername>/oauth-consumers/new und füge die Berechtigung „Account“ – „Read“ hinzu.
|
||||||
auths.tip.dropbox=Erstelle eine neue App auf https://www.dropbox.com/developers/apps.
|
auths.tip.dropbox=Erstelle eine neue App auf https://www.dropbox.com/developers/apps.
|
||||||
auths.tip.facebook=Erstelle eine neue Anwendung auf https://developers.facebook.com/apps und füge das Produkt "Facebook Login" hinzu.
|
auths.tip.facebook=Erstelle eine neue Anwendung auf https://developers.facebook.com/apps und füge das Produkt „Facebook Login“ hinzu.
|
||||||
auths.tip.github=Erstelle unter https://github.com/settings/applications/new eine neue OAuth Anwendung.
|
auths.tip.github=Erstelle unter https://github.com/settings/applications/new eine neue OAuth-Anwendung.
|
||||||
auths.tip.gitlab=Erstelle unter https://gitlab.com/profile/applications eine neue Anwendung.
|
auths.tip.gitlab=Erstelle unter https://gitlab.com/profile/applications eine neue Anwendung.
|
||||||
auths.tip.google_plus=Du erhältst die OAuth2 Client Zugangsdaten in der Google API Console unter https://console.developers.google.com/
|
auths.tip.google_plus=Du erhältst die OAuth2-Client-Zugangsdaten in der Google-API-Konsole unter https://console.developers.google.com/
|
||||||
auths.tip.openid_connect=Benutze die OpenID Connect Discovery URL (<server>/.well-known/openid-configuration) als Endpunkt.
|
auths.tip.openid_connect=Benutze die OpenID Connect Discovery URL (<server>/.well-known/openid-configuration) als Endpunkt.
|
||||||
auths.tip.twitter=Gehe auf https://dev.twitter.com/apps, erstelle eine Anwendung und stelle sicher, dass die Option “Allow this application to be used to Sign in with Twitter” aktiviert ist
|
auths.tip.twitter=Gehe auf https://dev.twitter.com/apps, erstelle eine Anwendung und stelle sicher, dass die Option „Allow this application to be used to Sign in with Twitter“ aktiviert ist
|
||||||
auths.edit=Authentifikationsquelle bearbeiten
|
auths.edit=Authentifikationsquelle bearbeiten
|
||||||
auths.activated=Diese Authentifikationsquelle ist aktiviert
|
auths.activated=Diese Authentifikationsquelle ist aktiviert
|
||||||
auths.new_success=Die Authentifizierung "%s" wurde hinzugefügt.
|
auths.new_success=Die Authentifizierung „%s“ wurde hinzugefügt.
|
||||||
auths.update_success=Diese Authentifizierungsquelle wurde aktualisiert.
|
auths.update_success=Diese Authentifizierungsquelle wurde aktualisiert.
|
||||||
auths.update=Authentifizierungsquelle aktualisieren
|
auths.update=Authentifizierungsquelle aktualisieren
|
||||||
auths.delete=Authentifikationsquelle löschen
|
auths.delete=Authentifikationsquelle löschen
|
||||||
auths.delete_auth_title=Authentifizierungsquelle löschen
|
auths.delete_auth_title=Authentifizierungsquelle löschen
|
||||||
auths.delete_auth_desc=Das Löschen einer Authentifizierungsquelle verhindert, dass Benutzer sich darüber anmelden können. Fortfahren?
|
auths.delete_auth_desc=Das Löschen einer Authentifizierungsquelle verhindert, dass Benutzer sich darüber anmelden können. Fortfahren?
|
||||||
auths.still_in_used=Diese Authentifizierungsquelle wird noch verwendet. Bearbeite oder lösche zuerst alle Benutzer, die diese Authentifizierungsquelle benutzen.
|
auths.still_in_used=Diese Authentifizierungsquelle wird noch verwendet. Bearbeite oder lösche zuerst alle Benutzer, die diese Authentifizierungsquelle benutzen.
|
||||||
auths.deletion_success=Die Authentifizierungsquelle '%s' wurde gelöscht.
|
auths.deletion_success=Die Authentifizierungsquelle „%s“ wurde gelöscht.
|
||||||
auths.login_source_exist=Die Authentifizierungsquelle '%s' existiert bereits.
|
auths.login_source_exist=Die Authentifizierungsquelle „%s“ existiert bereits.
|
||||||
|
|
||||||
config.server_config=Serverkonfiguration
|
config.server_config=Serverkonfiguration
|
||||||
config.app_name=Seitentitel
|
config.app_name=Seitentitel
|
||||||
config.app_ver=Gitea Version
|
config.app_ver=Gitea-Version
|
||||||
config.app_url=Gitea Basis-URL
|
config.app_url=Gitea-Basis-URL
|
||||||
config.custom_conf=Konfigurations-Datei-Pfad
|
config.custom_conf=Konfigurations-Datei-Pfad
|
||||||
config.domain=SSH Server-Domain
|
config.domain=SSH-Server-Domain
|
||||||
config.offline_mode=Lokaler Modus
|
config.offline_mode=Lokaler Modus
|
||||||
config.disable_router_log=Router-Log deaktivieren
|
config.disable_router_log=Router-Log deaktivieren
|
||||||
config.run_user=Ausführen als
|
config.run_user=Ausführen als
|
||||||
config.run_mode=Laufzeit-Modus
|
config.run_mode=Laufzeit-Modus
|
||||||
config.git_version=Git Version
|
config.git_version=Git-Version
|
||||||
config.repo_root_path=Repository-Verzeichnis
|
config.repo_root_path=Repository-Wurzelpfad
|
||||||
config.lfs_root_path=LFS-Wurzelpfad
|
config.lfs_root_path=LFS-Wurzelpfad
|
||||||
config.static_file_root_path=Verzeichnis für statische Dateien
|
config.static_file_root_path=Verzeichnis für statische Dateien
|
||||||
config.log_file_root_path=Logdateipfad
|
config.log_file_root_path=Logdateipfad
|
||||||
config.script_type=Skript-Typ
|
config.script_type=Skript-Typ
|
||||||
config.reverse_auth_user=Nutzer bei Reverse-Authentifizierung
|
config.reverse_auth_user=Nutzer bei Reverse-Authentifizierung
|
||||||
|
|
||||||
config.ssh_config=SSH Konfiguration
|
config.ssh_config=SSH-Konfiguration
|
||||||
config.ssh_enabled=Aktiviert
|
config.ssh_enabled=Aktiviert
|
||||||
config.ssh_start_builtin_server=Eingebauten Server verwenden
|
config.ssh_start_builtin_server=Eingebauten Server verwenden
|
||||||
config.ssh_domain=Server-Domain
|
config.ssh_domain=Server-Domain
|
||||||
|
|
@ -1465,9 +1467,9 @@ config.ssh_port=Port
|
||||||
config.ssh_listen_port=Listen-Port
|
config.ssh_listen_port=Listen-Port
|
||||||
config.ssh_root_path=Wurzelverzeichnis
|
config.ssh_root_path=Wurzelverzeichnis
|
||||||
config.ssh_key_test_path=Schlüssel-Test-Pfad
|
config.ssh_key_test_path=Schlüssel-Test-Pfad
|
||||||
config.ssh_keygen_path=Keygen ('ssh-keygen') Pfad
|
config.ssh_keygen_path=Keygen-Pfad („ssh-keygen“)
|
||||||
config.ssh_minimum_key_size_check=Prüfung der Mindestschlüssellänge
|
config.ssh_minimum_key_size_check=Prüfung der Mindestschlüssellänge
|
||||||
config.ssh_minimum_key_sizes=Minimale Schlüssellängen
|
config.ssh_minimum_key_sizes=Mindestschlüssellängen
|
||||||
|
|
||||||
config.db_config=Datenbankkonfiguration
|
config.db_config=Datenbankkonfiguration
|
||||||
config.db_type=Typ
|
config.db_type=Typ
|
||||||
|
|
@ -1481,17 +1483,17 @@ config.service_config=Service-Konfiguration
|
||||||
config.register_email_confirm=E-Mail-Bestätigung benötigt zum Registrieren
|
config.register_email_confirm=E-Mail-Bestätigung benötigt zum Registrieren
|
||||||
config.disable_register=Selbstegistrierung deaktivieren
|
config.disable_register=Selbstegistrierung deaktivieren
|
||||||
config.allow_only_external_registration=Registrierung nur über externe Services aktiveren
|
config.allow_only_external_registration=Registrierung nur über externe Services aktiveren
|
||||||
config.enable_openid_signup=OpenID Selbstregistrierung aktivieren
|
config.enable_openid_signup=OpenID-Selbstregistrierung aktivieren
|
||||||
config.enable_openid_signin=OpenID Anmeldung aktivieren
|
config.enable_openid_signin=OpenID-Anmeldung aktivieren
|
||||||
config.show_registration_button=Schaltfläche zum Registrieren anzeigen
|
config.show_registration_button=Schaltfläche zum Registrieren anzeigen
|
||||||
config.require_sign_in_view=Seiten nur für angemeldete Benutzer zugänglich
|
config.require_sign_in_view=Seiten nur für angemeldete Benutzer zugänglich
|
||||||
config.mail_notify=E-Mail-Benachrichtigungen aktivieren
|
config.mail_notify=E-Mail-Benachrichtigungen aktivieren
|
||||||
config.disable_key_size_check=Prüfung der Mindestschlüssellänge deaktiveren
|
config.disable_key_size_check=Prüfung der Mindestschlüssellänge deaktiveren
|
||||||
config.enable_captcha=CAPTCHA aktivieren
|
config.enable_captcha=CAPTCHA aktivieren
|
||||||
config.active_code_lives=Aktivierungscode Lebensdauer
|
config.active_code_lives=Aktivierungscode-Lebensdauer
|
||||||
config.reset_password_code_lives=Ablaufdatum des Passworts zurücksetzen
|
config.reset_password_code_lives=Ablaufdatum des Passworts zurücksetzen
|
||||||
config.default_keep_email_private=E-Mail-Adressen standardmäßig verbergen
|
config.default_keep_email_private=E-Mail-Adressen standardmäßig verbergen
|
||||||
config.default_allow_create_organization=Erstellen von Organisationen standarmäßig erlauben
|
config.default_allow_create_organization=Erstellen von Organisationen standardmäßig erlauben
|
||||||
config.enable_timetracking=Zeiterfassung aktivieren
|
config.enable_timetracking=Zeiterfassung aktivieren
|
||||||
config.default_enable_timetracking=Zeiterfassung standardmäßig aktivieren
|
config.default_enable_timetracking=Zeiterfassung standardmäßig aktivieren
|
||||||
config.default_allow_only_contributors_to_track_time=Nur Mitarbeitern erlauben, die Zeiterfassung zu nutzen
|
config.default_allow_only_contributors_to_track_time=Nur Mitarbeitern erlauben, die Zeiterfassung zu nutzen
|
||||||
|
|
@ -1500,11 +1502,11 @@ config.no_reply_address=Versteckte E-Mail-Domain
|
||||||
config.webhook_config=Webhook-Konfiguration
|
config.webhook_config=Webhook-Konfiguration
|
||||||
config.queue_length=Warteschlangenlänge
|
config.queue_length=Warteschlangenlänge
|
||||||
config.deliver_timeout=Zeitlimit für Zustellung
|
config.deliver_timeout=Zeitlimit für Zustellung
|
||||||
config.skip_tls_verify=TLS Verifikation überspringen
|
config.skip_tls_verify=TLS-Verifikation überspringen
|
||||||
|
|
||||||
config.mailer_config=SMTP Mailer Konfiguration
|
config.mailer_config=SMTP-Mailer-Konfiguration
|
||||||
config.mailer_enabled=Aktiviert
|
config.mailer_enabled=Aktiviert
|
||||||
config.mailer_disable_helo=HELO Deaktivieren
|
config.mailer_disable_helo=HELO deaktivieren
|
||||||
config.mailer_name=Name
|
config.mailer_name=Name
|
||||||
config.mailer_host=Host
|
config.mailer_host=Host
|
||||||
config.mailer_user=Benutzer
|
config.mailer_user=Benutzer
|
||||||
|
|
@ -1512,8 +1514,8 @@ config.mailer_use_sendmail=Sendmail benutzen
|
||||||
config.mailer_sendmail_path=Sendmail-Pfad
|
config.mailer_sendmail_path=Sendmail-Pfad
|
||||||
config.mailer_sendmail_args=Zusätzliche Argumente für Sendmail
|
config.mailer_sendmail_args=Zusätzliche Argumente für Sendmail
|
||||||
config.send_test_mail=Test-E-Mail senden
|
config.send_test_mail=Test-E-Mail senden
|
||||||
config.test_mail_failed=Das Senden der Test-E-Mail an '%s' ist fehlgeschlagen: %v
|
config.test_mail_failed=Das Senden der Test-E-Mail an „%s“ ist fehlgeschlagen: %v
|
||||||
config.test_mail_sent=Eine Test-E-Mail wurde an '%s' gesendet.
|
config.test_mail_sent=Eine Test-E-Mail wurde an „%s“ gesendet.
|
||||||
|
|
||||||
config.oauth_config=OAuth-Konfiguration
|
config.oauth_config=OAuth-Konfiguration
|
||||||
config.oauth_enabled=Aktiviert
|
config.oauth_enabled=Aktiviert
|
||||||
|
|
@ -1533,16 +1535,16 @@ config.session_life_time=Session-Lebensdauer
|
||||||
config.https_only=Nur HTTPS
|
config.https_only=Nur HTTPS
|
||||||
config.cookie_life_time=Cookie-Lebensdauer
|
config.cookie_life_time=Cookie-Lebensdauer
|
||||||
|
|
||||||
config.picture_config=Avatar-Konfiguration
|
config.picture_config=Bild-und-Profilbild-Konfiguration
|
||||||
config.picture_service=Bilderservice
|
config.picture_service=Bilderservice
|
||||||
config.disable_gravatar=Gravatar deaktivieren
|
config.disable_gravatar=Gravatar deaktivieren
|
||||||
config.enable_federated_avatar=Föderierte Profilbilder einschalten
|
config.enable_federated_avatar=Föderierte Profilbilder einschalten
|
||||||
|
|
||||||
config.git_config=Git Konfiguration
|
config.git_config=Git-Konfiguration
|
||||||
config.git_disable_diff_highlight=Diff Syntaxhervorhebung ausschalten
|
config.git_disable_diff_highlight=Diff-Syntaxhervorhebung ausschalten
|
||||||
config.git_max_diff_lines=Max Diff Zeilen (in einer Datei)
|
config.git_max_diff_lines=Max. Diff-Zeilen (in einer Datei)
|
||||||
config.git_max_diff_line_characters=Max Diff Zeichen (in einer Zeile)
|
config.git_max_diff_line_characters=Max. Diff-Zeichen (in einer Zeile)
|
||||||
config.git_max_diff_files=Max Diff Dateien (Anzeige)
|
config.git_max_diff_files=Max. Diff-Dateien (Angezeigte)
|
||||||
config.git_gc_args=GC-Argumente
|
config.git_gc_args=GC-Argumente
|
||||||
config.git_migrate_timeout=Zeitlimit für Migration
|
config.git_migrate_timeout=Zeitlimit für Migration
|
||||||
config.git_mirror_timeout=Zeitlimit für Mirror-Aktualisierung
|
config.git_mirror_timeout=Zeitlimit für Mirror-Aktualisierung
|
||||||
|
|
@ -1638,12 +1640,12 @@ mark_all_as_read=Alle als gelesen markieren
|
||||||
[gpg]
|
[gpg]
|
||||||
error.extract_sign=Die Signatur konnte nicht extrahiert werden
|
error.extract_sign=Die Signatur konnte nicht extrahiert werden
|
||||||
error.generate_hash=Es konnte kein Hash vom Commit generiert werden
|
error.generate_hash=Es konnte kein Hash vom Commit generiert werden
|
||||||
error.no_committer_account=Es ist kein Benutzerkonto mit dieser Commiter-Email verbunden
|
error.no_committer_account=Es ist kein Benutzerkonto mit der E-Mail-Adresse des Committers verbunden
|
||||||
error.no_gpg_keys_found=Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
|
error.no_gpg_keys_found=Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
|
||||||
error.not_signed_commit=Kein signierter Commit
|
error.not_signed_commit=Kein signierter Commit
|
||||||
error.failed_retrieval_gpg_keys=Fehler beim Abrufen eines Keys des Commiter-Kontos
|
error.failed_retrieval_gpg_keys=Fehler beim Abrufen eines Keys des Commiter-Kontos
|
||||||
|
|
||||||
[units]
|
[units]
|
||||||
error.no_unit_allowed_repo=Du hast keine Berechtigung auf einen Bereich dieses Repositories zuzugreifen.
|
error.no_unit_allowed_repo=Du hast keine Berechtigung, um auf irgendeinen Bereich dieses Repositories zuzugreifen.
|
||||||
error.unit_not_allowed=Du hast keine Berechtigung auf diesen Repository-Bereich zuzugreifen.
|
error.unit_not_allowed=Du hast keine Berechtigung, um auf diesen Repository-Bereich zuzugreifen.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ send_reset_mail = Click here to resend your password reset email
|
||||||
reset_password = Reset Your Password
|
reset_password = Reset Your Password
|
||||||
invalid_code = Your confirmation code is invalid or has expired.
|
invalid_code = Your confirmation code is invalid or has expired.
|
||||||
reset_password_helper = Click here to reset your password
|
reset_password_helper = Click here to reset your password
|
||||||
password_too_short = Password length cannot be less then %d.
|
password_too_short = Password length cannot be less than %d characters.
|
||||||
non_local_account = Non-local users can not update their password through the Gitea web interface.
|
non_local_account = Non-local users can not update their password through the Gitea web interface.
|
||||||
verify = Verify
|
verify = Verify
|
||||||
scratch_code = Scratch code
|
scratch_code = Scratch code
|
||||||
|
|
@ -1167,6 +1167,8 @@ branch.protected_deletion_failed = Branch '%s' is protected. It cannot be delete
|
||||||
|
|
||||||
topic.manage_topics = Manage Topics
|
topic.manage_topics = Manage Topics
|
||||||
topic.done = Done
|
topic.done = Done
|
||||||
|
topic.count_prompt = You can't select more than 25 topics
|
||||||
|
topic.format_prompt = Topics must start with a letter or number, can include hyphens(-) and must be no more than 35 characters long
|
||||||
|
|
||||||
[org]
|
[org]
|
||||||
org_name_holder = Organization Name
|
org_name_holder = Organization Name
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,6 @@ email_not_associate=Esta dirección de correo electrónico no esta asociada a ni
|
||||||
send_reset_mail=Haz clic aquí para reenviar tu email de restauración de contraseña
|
send_reset_mail=Haz clic aquí para reenviar tu email de restauración de contraseña
|
||||||
reset_password=Restablecer su contraseña
|
reset_password=Restablecer su contraseña
|
||||||
reset_password_helper=Haga Clic aquí para restablecer su contraseña
|
reset_password_helper=Haga Clic aquí para restablecer su contraseña
|
||||||
password_too_short=La longitud de la contraseña no puede ser menor a %d.
|
|
||||||
verify=Verificar
|
verify=Verificar
|
||||||
twofa_scratch_used=Ya has utilizado el código. Has sido redirigido a la página de configuración de dos factores poder remover la inscripción del dispositivo o generar un nuevo código.
|
twofa_scratch_used=Ya has utilizado el código. Has sido redirigido a la página de configuración de dos factores poder remover la inscripción del dispositivo o generar un nuevo código.
|
||||||
twofa_scratch_token_incorrect=El código cero es incorrecto.
|
twofa_scratch_token_incorrect=El código cero es incorrecto.
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,6 @@ has_unconfirmed_mail=Hei %s, sinulla on varmistamaton sähköposti osoite (<b>%s
|
||||||
resend_mail=Klikkaa tästä uudelleenlähettääksesi aktivointi sähköpostisi
|
resend_mail=Klikkaa tästä uudelleenlähettääksesi aktivointi sähköpostisi
|
||||||
reset_password=Nollaa salasanasi
|
reset_password=Nollaa salasanasi
|
||||||
reset_password_helper=Klikkaa tästä nollataksesi salasanasi
|
reset_password_helper=Klikkaa tästä nollataksesi salasanasi
|
||||||
password_too_short=Salasanan pituus ei voi olla vähemmän kuin %d merkkiä.
|
|
||||||
verify=Vahvista
|
verify=Vahvista
|
||||||
|
|
||||||
[mail]
|
[mail]
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,6 @@ email_not_associate=L'adresse e-mail n'est associée à aucun compte.
|
||||||
send_reset_mail=Cliquez ici pour renvoyer le mail de réinitialisation de votre mot de passe
|
send_reset_mail=Cliquez ici pour renvoyer le mail de réinitialisation de votre mot de passe
|
||||||
reset_password=Réinitialiser le mot de passe
|
reset_password=Réinitialiser le mot de passe
|
||||||
reset_password_helper=Cliquez ici pour réinitialiser votre mot de passe
|
reset_password_helper=Cliquez ici pour réinitialiser votre mot de passe
|
||||||
password_too_short=Le mot de passe doit contenir %d caractères minimum.
|
|
||||||
verify=Vérifier
|
verify=Vérifier
|
||||||
scratch_code=Code de secours
|
scratch_code=Code de secours
|
||||||
use_scratch_code=Utiliser un code de secours
|
use_scratch_code=Utiliser un code de secours
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,6 @@ email_not_associate=Az email cím nincsen hozzárendelve egyetlen fiókhoz sem.
|
||||||
send_reset_mail=Kattints ide hogy újraküldd a jelszó visszaállító emailt
|
send_reset_mail=Kattints ide hogy újraküldd a jelszó visszaállító emailt
|
||||||
reset_password=Jelszó visszaállítása
|
reset_password=Jelszó visszaállítása
|
||||||
reset_password_helper=Kattintson ide, hogy visszaállítsa a jelszavát
|
reset_password_helper=Kattintson ide, hogy visszaállítsa a jelszavát
|
||||||
password_too_short=A jelszó nem lehet rövidebb, mint %d karakter.
|
|
||||||
verify=Ellenőrzés
|
verify=Ellenőrzés
|
||||||
scratch_code=Kaparós kód
|
scratch_code=Kaparós kód
|
||||||
use_scratch_code=Kaparós kód használata
|
use_scratch_code=Kaparós kód használata
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,6 @@ email_not_associate=Alamat surel tidak terhubung dengan akun apapun.
|
||||||
send_reset_mail=Klik di sini untuk mengirim ulang surel pengaturan ulang kata sandi
|
send_reset_mail=Klik di sini untuk mengirim ulang surel pengaturan ulang kata sandi
|
||||||
reset_password=Atur Ulang Kata Sandi Anda
|
reset_password=Atur Ulang Kata Sandi Anda
|
||||||
reset_password_helper=Klik di sini untuk mengatur ulang kata sandi anda
|
reset_password_helper=Klik di sini untuk mengatur ulang kata sandi anda
|
||||||
password_too_short=Panjang kata sandi tidak boleh kurang dari %d.
|
|
||||||
verify=Verifikasi
|
verify=Verifikasi
|
||||||
scratch_code=Kode coretan
|
scratch_code=Kode coretan
|
||||||
use_scratch_code=Gunakan kode coretan
|
use_scratch_code=Gunakan kode coretan
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,6 @@ email_not_associate=L'indirizzo email non è associato ad alcuna conta.
|
||||||
send_reset_mail=Clicca qui per inviare nuovamente la tua email di reimpostazione della password
|
send_reset_mail=Clicca qui per inviare nuovamente la tua email di reimpostazione della password
|
||||||
reset_password=Reimposta la tua Password
|
reset_password=Reimposta la tua Password
|
||||||
reset_password_helper=Clicca qui per reimpostare la password
|
reset_password_helper=Clicca qui per reimpostare la password
|
||||||
password_too_short=La lunghezza della password non può essere meno %d caratteri.
|
|
||||||
verify=Verifica
|
verify=Verifica
|
||||||
scratch_code=Codice Gratta e Vinci
|
scratch_code=Codice Gratta e Vinci
|
||||||
use_scratch_code=Utilizza un codice di zero
|
use_scratch_code=Utilizza un codice di zero
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,6 @@ email_not_associate=このEメールアドレスは、どのアカウントに
|
||||||
send_reset_mail=パスワードリセットメールを再送するにはここをクリックしてください
|
send_reset_mail=パスワードリセットメールを再送するにはここをクリックしてください
|
||||||
reset_password=パスワードリセット
|
reset_password=パスワードリセット
|
||||||
reset_password_helper=パスワードをリセットするにはここをクリック
|
reset_password_helper=パスワードをリセットするにはここをクリック
|
||||||
password_too_short=%d文字未満のパスワードは設定できません。
|
|
||||||
verify=確認
|
verify=確認
|
||||||
scratch_code=スクラッチコード
|
scratch_code=スクラッチコード
|
||||||
use_scratch_code=スクラッチコードを使う
|
use_scratch_code=スクラッチコードを使う
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,6 @@ email_not_associate=이 이메일 주소로 등록된 계정이 없습니다.
|
||||||
send_reset_mail=여기를 눌러 비밀번호 초기화 메일을 재전송
|
send_reset_mail=여기를 눌러 비밀번호 초기화 메일을 재전송
|
||||||
reset_password=비밀번호 초기화
|
reset_password=비밀번호 초기화
|
||||||
reset_password_helper=이곳을 눌러 비밀번호를 재설정
|
reset_password_helper=이곳을 눌러 비밀번호를 재설정
|
||||||
password_too_short=비밀번호의 길이는 %d글자 미만일 수 없습니다.
|
|
||||||
verify=확인
|
verify=확인
|
||||||
scratch_code=스크래치 코드
|
scratch_code=스크래치 코드
|
||||||
use_scratch_code=스크래치 코드 사용
|
use_scratch_code=스크래치 코드 사용
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,6 @@ active_your_account=Aktyvinkite savo paskyrą
|
||||||
resend_mail=Spauskite čia norėdami persiųsti aktyvacijos laišką
|
resend_mail=Spauskite čia norėdami persiųsti aktyvacijos laišką
|
||||||
reset_password=Atstatyti slaptažodį
|
reset_password=Atstatyti slaptažodį
|
||||||
reset_password_helper=Paspauskite čia norėdami pakeisti savo slaptažodį
|
reset_password_helper=Paspauskite čia norėdami pakeisti savo slaptažodį
|
||||||
password_too_short=Slaptažodis negali būti trumpesnis nei %d simbolių.
|
|
||||||
verify=Patikrinti
|
verify=Patikrinti
|
||||||
|
|
||||||
[mail]
|
[mail]
|
||||||
|
|
|
||||||
|
|
@ -54,13 +54,14 @@ password=Parole
|
||||||
db_name=Datu bāzes nosaukums
|
db_name=Datu bāzes nosaukums
|
||||||
path=Ceļš
|
path=Ceļš
|
||||||
|
|
||||||
repo_path=Repozitoriju glabāšanas vieta
|
repo_path=Repozitoriju glabāšanas ceļš
|
||||||
log_root_path=Žurnalizēšanas direktorija
|
log_root_path=Žurnalizēšanas ceļš
|
||||||
|
|
||||||
optional_title=Neobligātie iestatījumi
|
optional_title=Neobligātie iestatījumi
|
||||||
smtp_host=SMTP resursdators
|
smtp_host=SMTP resursdators
|
||||||
federated_avatar_lookup_popup=Iespējot apvienoto profila bilžu meklētāju, lai izmantotu atvērtā koda apvienoto servisu balstītu uz libravatar.
|
federated_avatar_lookup_popup=Iespējot apvienoto profila bilžu meklētāju, lai izmantotu atvērtā koda apvienoto servisu balstītu uz libravatar.
|
||||||
openid_signin=Iespējot OpenID autorizāciju
|
openid_signin=Iespējot OpenID autorizāciju
|
||||||
|
openid_signin_popup=Iespējot lietotāju autorizāciju ar OpenID.
|
||||||
enable_captcha_popup=Lietotājam reģistrējoties, pieprasīt ievadīt drošības kodu.
|
enable_captcha_popup=Lietotājam reģistrējoties, pieprasīt ievadīt drošības kodu.
|
||||||
admin_password=Parole
|
admin_password=Parole
|
||||||
confirm_password=Apstipriniet paroli
|
confirm_password=Apstipriniet paroli
|
||||||
|
|
@ -101,7 +102,6 @@ email_not_associate=Šī e-pasta adrese nav saistīta ar nevienu kontu.
|
||||||
send_reset_mail=Spiediet šeit, lai nosūtītu paroles maiņas vēstuli uz Jūsu e-pastu
|
send_reset_mail=Spiediet šeit, lai nosūtītu paroles maiņas vēstuli uz Jūsu e-pastu
|
||||||
reset_password=Atjaunot savu paroli
|
reset_password=Atjaunot savu paroli
|
||||||
reset_password_helper=Nospiediet šeit, lai atjaunotu paroli
|
reset_password_helper=Nospiediet šeit, lai atjaunotu paroli
|
||||||
password_too_short=Paroles garums nedrīkst būt mazāks par %d.
|
|
||||||
verify=Pārbaudīt
|
verify=Pārbaudīt
|
||||||
scratch_code=Vienreizējais kods
|
scratch_code=Vienreizējais kods
|
||||||
use_scratch_code=Izmantot vienreizējo kodu
|
use_scratch_code=Izmantot vienreizējo kodu
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,6 @@ email_not_associate=Dit emailadres is niet gekoppeld aan een account.
|
||||||
send_reset_mail=Klik hier om de wachtwoord reset mail (nogmaals) te versturen
|
send_reset_mail=Klik hier om de wachtwoord reset mail (nogmaals) te versturen
|
||||||
reset_password=Reset uw wachtwoord
|
reset_password=Reset uw wachtwoord
|
||||||
reset_password_helper=Klik hier om uw wachtwoord opnieuw in te stellen.
|
reset_password_helper=Klik hier om uw wachtwoord opnieuw in te stellen.
|
||||||
password_too_short=De lengte van uw wachtwoord moet minimaal %d karakters zijn.
|
|
||||||
verify=Verifiëren
|
verify=Verifiëren
|
||||||
scratch_code=Eenmalige code
|
scratch_code=Eenmalige code
|
||||||
use_scratch_code=Gebruik een eenmalige code
|
use_scratch_code=Gebruik een eenmalige code
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,6 @@ email_not_associate=Adres e-mail nie jest powiązany z żadnym kontem.
|
||||||
send_reset_mail=Kliknij tutaj, aby ponownie wysłać e-mail resetowania hasła
|
send_reset_mail=Kliknij tutaj, aby ponownie wysłać e-mail resetowania hasła
|
||||||
reset_password=Resetowanie hasła
|
reset_password=Resetowanie hasła
|
||||||
reset_password_helper=Kliknij tutaj, aby zresetować hasło
|
reset_password_helper=Kliknij tutaj, aby zresetować hasło
|
||||||
password_too_short=Długość hasła nie może być mniejsza niż %d znaków.
|
|
||||||
verify=Potwierdź
|
verify=Potwierdź
|
||||||
scratch_code=Kod jednorazowy
|
scratch_code=Kod jednorazowy
|
||||||
use_scratch_code=Użyj kodu jednorazowego
|
use_scratch_code=Użyj kodu jednorazowego
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ send_reset_mail=Clique aqui para re-enviar seu e-mail de redefinição de senha
|
||||||
reset_password=Redefinir sua senha
|
reset_password=Redefinir sua senha
|
||||||
invalid_code=Seu código de confirmação é inválido ou expirou.
|
invalid_code=Seu código de confirmação é inválido ou expirou.
|
||||||
reset_password_helper=Clique aqui para redefinir sua senha
|
reset_password_helper=Clique aqui para redefinir sua senha
|
||||||
password_too_short=O comprimento da senha não pode ser menor que %d.
|
password_too_short=A senha deve ter %d ou mais caracteres.
|
||||||
non_local_account=Usuários não-locais não podem atualizar sua senha através da interface web do Gitea.
|
non_local_account=Usuários não-locais não podem atualizar sua senha através da interface web do Gitea.
|
||||||
verify=Verificar
|
verify=Verificar
|
||||||
scratch_code=Código de backup
|
scratch_code=Código de backup
|
||||||
|
|
@ -1167,6 +1167,8 @@ branch.protected_deletion_failed=A branch '%s' está protegida. Ela não pode se
|
||||||
|
|
||||||
topic.manage_topics=Gerenciar Tópicos
|
topic.manage_topics=Gerenciar Tópicos
|
||||||
topic.done=Feito
|
topic.done=Feito
|
||||||
|
topic.count_prompt=Você não pode selecionar mais de 25 tópicos
|
||||||
|
topic.format_prompt=Tópicos devem começar com uma letra ou um número, podem incluir hífens (-) e não devem ter mais de 35 caracteres
|
||||||
|
|
||||||
[org]
|
[org]
|
||||||
org_name_holder=Nome da organização
|
org_name_holder=Nome da organização
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ send_reset_mail=Нажмите сюда, чтобы отправить пись
|
||||||
reset_password=Сброс пароля
|
reset_password=Сброс пароля
|
||||||
invalid_code=Этот код подтверждения недействителен или истек.
|
invalid_code=Этот код подтверждения недействителен или истек.
|
||||||
reset_password_helper=Нажмите здесь, чтобы сбросить свой пароль
|
reset_password_helper=Нажмите здесь, чтобы сбросить свой пароль
|
||||||
password_too_short=Длина пароля не менее %d символов.
|
password_too_short=Длина пароля не может быть меньше, чем %d символов.
|
||||||
non_local_account=Нелокальные аккаунты не могут изменить пароль через Gitea.
|
non_local_account=Нелокальные аккаунты не могут изменить пароль через Gitea.
|
||||||
verify=Проверить
|
verify=Проверить
|
||||||
scratch_code=Одноразовый пароль
|
scratch_code=Одноразовый пароль
|
||||||
|
|
@ -490,7 +490,7 @@ delete_account_desc=Вы уверены, что хотите навсегда у
|
||||||
[repo]
|
[repo]
|
||||||
owner=Владелец
|
owner=Владелец
|
||||||
repo_name=Имя репозитория
|
repo_name=Имя репозитория
|
||||||
repo_name_helper=Лучшие названия репозиториев состоят их коротких, легко запоминаемых и уникальных ключевых слов.
|
repo_name_helper=Лучшие названия репозиториев состоят из коротких, легко запоминаемых и уникальных ключевых слов.
|
||||||
visibility=Видимость
|
visibility=Видимость
|
||||||
visiblity_helper=Сделать репозиторий приватным
|
visiblity_helper=Сделать репозиторий приватным
|
||||||
visiblity_helper_forced=Администратор сайта настроил параметр видимости новых репозиториев. Репозиторий приватный по умолчанию.
|
visiblity_helper_forced=Администратор сайта настроил параметр видимости новых репозиториев. Репозиторий приватный по умолчанию.
|
||||||
|
|
@ -1167,6 +1167,8 @@ branch.protected_deletion_failed=Ветка '%s' защищена. Её нель
|
||||||
|
|
||||||
topic.manage_topics=Редактировать тематические метки
|
topic.manage_topics=Редактировать тематические метки
|
||||||
topic.done=Сохранить
|
topic.done=Сохранить
|
||||||
|
topic.count_prompt=Вы не можете выбрать более 25 тем
|
||||||
|
topic.format_prompt=Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов
|
||||||
|
|
||||||
[org]
|
[org]
|
||||||
org_name_holder=Название организации
|
org_name_holder=Название организации
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,6 @@ has_unconfirmed_mail=Здраво, %s! Имате непотврђену адр
|
||||||
resend_mail=Кликните овде да поново пошаљете писмо
|
resend_mail=Кликните овде да поново пошаљете писмо
|
||||||
reset_password=Ресет лозинке
|
reset_password=Ресет лозинке
|
||||||
reset_password_helper=Кликните овде да ресетујете вашу лозинку
|
reset_password_helper=Кликните овде да ресетујете вашу лозинку
|
||||||
password_too_short=Лозинка неможе бити краћа од %d карактера.
|
|
||||||
|
|
||||||
[mail]
|
[mail]
|
||||||
activate_account=Молимо вас активирајте ваш налог
|
activate_account=Молимо вас активирајте ваш налог
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,6 @@ email_not_associate=Denna e-postadress är inte knutet till något konto.
|
||||||
send_reset_mail=Klicka här för att skicka e-post med lösenordsåterställning igen
|
send_reset_mail=Klicka här för att skicka e-post med lösenordsåterställning igen
|
||||||
reset_password=Återställ ditt lösenord
|
reset_password=Återställ ditt lösenord
|
||||||
reset_password_helper=Klicka här för att återställa ditt lösenord
|
reset_password_helper=Klicka här för att återställa ditt lösenord
|
||||||
password_too_short=Lösenordet får ej vara kortare än %d tecken.
|
|
||||||
verify=Verifiera
|
verify=Verifiera
|
||||||
scratch_code=Skrapkod
|
scratch_code=Skrapkod
|
||||||
use_scratch_code=Använd en skrapkod
|
use_scratch_code=Använd en skrapkod
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,6 @@ email_not_associate=Bu e-posta adresi hiçbir hesap ile ilişkilendirilmemiştir
|
||||||
send_reset_mail=Parola sıfırlama e-postasını (yeniden) göndermek için buraya tıklayın
|
send_reset_mail=Parola sıfırlama e-postasını (yeniden) göndermek için buraya tıklayın
|
||||||
reset_password=Parolanızı Sıfırlayın
|
reset_password=Parolanızı Sıfırlayın
|
||||||
reset_password_helper=Parolanızı sıfırlamak için buraya tıklayın
|
reset_password_helper=Parolanızı sıfırlamak için buraya tıklayın
|
||||||
password_too_short=Parola uzunluğu %d karakterden az olamaz.
|
|
||||||
verify=Doğrula
|
verify=Doğrula
|
||||||
scratch_code=Çizgi kodu
|
scratch_code=Çizgi kodu
|
||||||
use_scratch_code=Bir çizgi kodu kullanınız
|
use_scratch_code=Bir çizgi kodu kullanınız
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,10 @@ u2f_use_twofa=Використовуйте дво-факторний код з
|
||||||
u2f_error=Неможливо прочитати ваш ключ безпеки!
|
u2f_error=Неможливо прочитати ваш ключ безпеки!
|
||||||
u2f_unsupported_browser=Ваш браузер не підтримує U2F ключі. Будь ласка, спробуйте інший браузер.
|
u2f_unsupported_browser=Ваш браузер не підтримує U2F ключі. Будь ласка, спробуйте інший браузер.
|
||||||
u2f_error_1=Сталася невідома помилка. Спробуйте ще раз.
|
u2f_error_1=Сталася невідома помилка. Спробуйте ще раз.
|
||||||
|
u2f_error_2=Переконайтеся, що ви використовуєте зашифроване з'єднання (https://) та відвідуєте правильну URL-адресу.
|
||||||
u2f_error_3=Сервер не може обробити, ваш запит.
|
u2f_error_3=Сервер не може обробити, ваш запит.
|
||||||
|
u2f_error_4=Представлений ключ не дає право на цей запит. Якщо спробуєте зареєструвати його, переконайтеся, що ключ ще не зареєстровано.
|
||||||
|
u2f_error_5=Таймаут досягнуто до того, як ваш ключ можна буде прочитати. Перезавантажте, щоб повторити спробу.
|
||||||
u2f_reload=Оновити
|
u2f_reload=Оновити
|
||||||
|
|
||||||
repository=Репозиторій
|
repository=Репозиторій
|
||||||
|
|
@ -67,12 +70,12 @@ activities=Дії
|
||||||
pull_requests=Запити на злиття
|
pull_requests=Запити на злиття
|
||||||
issues=Проблеми
|
issues=Проблеми
|
||||||
|
|
||||||
cancel=Відміна
|
cancel=Відмінити
|
||||||
|
|
||||||
[install]
|
[install]
|
||||||
install=Встановлення
|
install=Встановлення
|
||||||
title=Початкова конфігурація
|
title=Початкова конфігурація
|
||||||
docker_helper=Якщо ви запускаєте Gitea всередині Docker, будь ласка уважно прочитайте <a target="_blank" rel="noopener" href="%s">документацію</a> перед тим, як що-небудь змінити на цій сторінці.
|
docker_helper=Якщо ви запускаєте Gitea всередині Docker, будь ласка уважно прочитайте <a target="_blank" rel="noopener" href="%s">документацію</a> перед тим, як щось змінити на цій сторінці.
|
||||||
requite_db_desc=Gitea потребує MySQL, PostgreSQL, MSSQL, SQLite3 або TiDB.
|
requite_db_desc=Gitea потребує MySQL, PostgreSQL, MSSQL, SQLite3 або TiDB.
|
||||||
db_title=Налаштування бази даних
|
db_title=Налаштування бази даних
|
||||||
db_type=Тип бази даних
|
db_type=Тип бази даних
|
||||||
|
|
@ -104,6 +107,7 @@ ssh_port_helper=Номер порту, який використовує SSH с
|
||||||
http_port=Gitea HTTP порт
|
http_port=Gitea HTTP порт
|
||||||
http_port_helper=Номер порту, який буде прослуховуватися Giteas веб-сервером.
|
http_port_helper=Номер порту, який буде прослуховуватися Giteas веб-сервером.
|
||||||
app_url=Базова URL-адреса Gitea
|
app_url=Базова URL-адреса Gitea
|
||||||
|
app_url_helper=Базова адреса для HTTP(S) клонування через URL та повідомлень електронної пошти.
|
||||||
log_root_path=Шлях до лог файлу
|
log_root_path=Шлях до лог файлу
|
||||||
log_root_path_helper=Файли журналу будуть записані в цей каталог.
|
log_root_path_helper=Файли журналу будуть записані в цей каталог.
|
||||||
|
|
||||||
|
|
@ -111,6 +115,7 @@ optional_title=Додаткові налаштування
|
||||||
email_title=Налаштування Email
|
email_title=Налаштування Email
|
||||||
smtp_host=SMTP хост
|
smtp_host=SMTP хост
|
||||||
smtp_from=Відправляти Email від імені
|
smtp_from=Відправляти Email від імені
|
||||||
|
smtp_from_helper=Електронна пошта для використання в Gіtea. Введіть звичайну електронну адресу або використовуйте формат: "Ім'я" <email@example.com>.
|
||||||
mailer_user=SMTP Ім'я кристувача
|
mailer_user=SMTP Ім'я кристувача
|
||||||
mailer_password=SMTP Пароль
|
mailer_password=SMTP Пароль
|
||||||
register_confirm=Потрібно підтвердити електронну пошту для реєстрації
|
register_confirm=Потрібно підтвердити електронну пошту для реєстрації
|
||||||
|
|
@ -124,9 +129,11 @@ federated_avatar_lookup=Увімкнути федеративні аватари
|
||||||
federated_avatar_lookup_popup=Увімкнути зовнішний Аватар за допомогою Libravatar.
|
federated_avatar_lookup_popup=Увімкнути зовнішний Аватар за допомогою Libravatar.
|
||||||
disable_registration=Вимкнути самостійну реєстрацію
|
disable_registration=Вимкнути самостійну реєстрацію
|
||||||
disable_registration_popup=Вимкнути самостійну реєстрацію користувачів, тільки адміністратор може створювати нові облікові записи.
|
disable_registration_popup=Вимкнути самостійну реєстрацію користувачів, тільки адміністратор може створювати нові облікові записи.
|
||||||
|
allow_only_external_registration_popup=Включити реєстрацію тільки через зовнішні сервіси.
|
||||||
openid_signin=Увімкнути реєстрацію за допомогою OpenID
|
openid_signin=Увімкнути реєстрацію за допомогою OpenID
|
||||||
openid_signin_popup=Увімкнути вхід за допомогою OpenID.
|
openid_signin_popup=Увімкнути вхід за допомогою OpenID.
|
||||||
openid_signup=Увімкнути самостійну реєстрацію за допомогою OpenID
|
openid_signup=Увімкнути самостійну реєстрацію за допомогою OpenID
|
||||||
|
openid_signup_popup=Увімкнути самореєстрацію користувачів на основі OpenID.
|
||||||
enable_captcha=Увімкнути CAPTCHA
|
enable_captcha=Увімкнути CAPTCHA
|
||||||
enable_captcha_popup=Вимагати перевірку CAPTCHA при самостійній реєстрації користувача.
|
enable_captcha_popup=Вимагати перевірку CAPTCHA при самостійній реєстрації користувача.
|
||||||
require_sign_in_view=Вимагати авторизації для перегляду сторінок
|
require_sign_in_view=Вимагати авторизації для перегляду сторінок
|
||||||
|
|
@ -140,6 +147,7 @@ admin_email=Адреса електронної пошти
|
||||||
install_btn_confirm=Встановлення Gitea
|
install_btn_confirm=Встановлення Gitea
|
||||||
test_git_failed=Не в змозі перевірити 'git' команду: %v
|
test_git_failed=Не в змозі перевірити 'git' команду: %v
|
||||||
invalid_db_setting=Налаштування бази даних є некоректними: %v
|
invalid_db_setting=Налаштування бази даних є некоректними: %v
|
||||||
|
invalid_repo_path=Помилковий шлях до кореня репозиторію: %v
|
||||||
save_config_failed=Не в змозі зберегти конфігурацію: %v
|
save_config_failed=Не в змозі зберегти конфігурацію: %v
|
||||||
invalid_admin_setting=Неприпустимі налаштування облікового запису адміністратора: %v
|
invalid_admin_setting=Неприпустимі налаштування облікового запису адміністратора: %v
|
||||||
install_success=Ласкаво просимо! Дякуємо вам за вибір Gitea. Розважайтеся, і будьте обережні!
|
install_success=Ласкаво просимо! Дякуємо вам за вибір Gitea. Розважайтеся, і будьте обережні!
|
||||||
|
|
@ -151,6 +159,7 @@ default_allow_create_organization_popup=Дозволити новим облік
|
||||||
default_enable_timetracking=Увімкнути відстеження часу за замовчуванням
|
default_enable_timetracking=Увімкнути відстеження часу за замовчуванням
|
||||||
default_enable_timetracking_popup=Включити відстеження часу для нових репозиторіїв за замовчуванням.
|
default_enable_timetracking_popup=Включити відстеження часу для нових репозиторіїв за замовчуванням.
|
||||||
no_reply_address=Прихований поштовий домен
|
no_reply_address=Прихований поштовий домен
|
||||||
|
no_reply_address_helper=Доменне ім'я для користувачів із прихованою електронною адресою. Наприклад, ім'я користувача 'joe' буде входити в Git як 'joe@noreply.example.org', якщо для прихованого домену електронної пошти встановлено 'noreply.example.org'.
|
||||||
|
|
||||||
[home]
|
[home]
|
||||||
uname_holder=Ім'я користувача або Ел. пошта
|
uname_holder=Ім'я користувача або Ел. пошта
|
||||||
|
|
@ -175,11 +184,13 @@ code=Код
|
||||||
repo_no_results=Відповідних репозиторіїв не знайдено.
|
repo_no_results=Відповідних репозиторіїв не знайдено.
|
||||||
user_no_results=Відповідних користувачів не знайдено.
|
user_no_results=Відповідних користувачів не знайдено.
|
||||||
org_no_results=Відповідних організацій не знайдено.
|
org_no_results=Відповідних організацій не знайдено.
|
||||||
|
code_no_results=Відповідний пошуковому запитанню код не знайдено.
|
||||||
code_search_results=Результати пошуку '%s'
|
code_search_results=Результати пошуку '%s'
|
||||||
|
|
||||||
[auth]
|
[auth]
|
||||||
create_new_account=Реєстрація облікового запису
|
create_new_account=Реєстрація облікового запису
|
||||||
register_helper_msg=Вже зареєстровані? Увійдіть зараз!
|
register_helper_msg=Вже зареєстровані? Увійдіть зараз!
|
||||||
|
social_register_helper_msg=Вже є аккаунт? Зв'яжіть його зараз!
|
||||||
disable_register_prompt=Вибачте, можливість реєстрації відключена. Будь ласка, зв'яжіться з адміністратором сайту.
|
disable_register_prompt=Вибачте, можливість реєстрації відключена. Будь ласка, зв'яжіться з адміністратором сайту.
|
||||||
disable_register_mail=Підтвердження реєстрації електронною поштою вимкнено.
|
disable_register_mail=Підтвердження реєстрації електронною поштою вимкнено.
|
||||||
remember_me=Запам'ятати мене
|
remember_me=Запам'ятати мене
|
||||||
|
|
@ -199,19 +210,22 @@ send_reset_mail=Натисніть сюди, щоб відправити лис
|
||||||
reset_password=Скинути пароль
|
reset_password=Скинути пароль
|
||||||
invalid_code=Цей код підтвердження недійсний або закінчився.
|
invalid_code=Цей код підтвердження недійсний або закінчився.
|
||||||
reset_password_helper=Натисніть тут для скидання пароля
|
reset_password_helper=Натисніть тут для скидання пароля
|
||||||
password_too_short=Довжина пароля не може бути меншою за %d.
|
password_too_short=Довжина пароля не може бути меншою за %d символів.
|
||||||
non_local_account=Нелокальні акаунти не можуть змінити пароль через Gitea.
|
non_local_account=Нелокальні акаунти не можуть змінити пароль через Gitea.
|
||||||
verify=Підтвердити
|
verify=Підтвердити
|
||||||
scratch_code=Одноразовий пароль
|
scratch_code=Одноразовий пароль
|
||||||
use_scratch_code=Використовувати одноразовий пароль
|
use_scratch_code=Використовувати одноразовий пароль
|
||||||
twofa_scratch_used=Ви використовували одноразовий пароль. Ви були перенаправлені на сторінку налаштувань для генерації нового коду або відключення двуфакторной аутентифікації.
|
twofa_scratch_used=Ви використовували одноразовий пароль. Ви були перенаправлені на сторінку налаштувань для генерації нового коду або відключення двуфакторної автентифікації.
|
||||||
twofa_passcode_incorrect=Ваш пароль є невірним. Якщо ви втратили пристрій, використовуйте ваш одноразовий пароль.
|
twofa_passcode_incorrect=Ваш пароль є невірним. Якщо ви втратили пристрій, використовуйте ваш одноразовий пароль.
|
||||||
twofa_scratch_token_incorrect=Невірний одноразовий пароль.
|
twofa_scratch_token_incorrect=Невірний одноразовий пароль.
|
||||||
login_userpass=Увійти
|
login_userpass=Увійти
|
||||||
login_openid=OpenID
|
login_openid=OpenID
|
||||||
openid_connect_submit=Під’єднатися
|
openid_connect_submit=Під’єднатися
|
||||||
openid_connect_title=Підключитися до існуючого облікового запису
|
openid_connect_title=Підключитися до існуючого облікового запису
|
||||||
|
openid_connect_desc=Вибраний OpenID URI невідомий. Пов'яжіть його з новим обліковим записом тут.
|
||||||
openid_register_title=Створити новий обліковий запис
|
openid_register_title=Створити новий обліковий запис
|
||||||
|
openid_register_desc=Вибраний OpenID URI невідомий. Пов'яжіть йогоз новим обліковим записом тут.
|
||||||
|
openid_signin_desc=Введіть свій ідентифікатор OpenID. Наприклад: https://anne.me, bob.openid.org.cn або gnusocial.net/carry.
|
||||||
disable_forgot_password_mail=На жаль скидання пароля відключене. Будь ласка, зв'яжіться з адміністратором сайту.
|
disable_forgot_password_mail=На жаль скидання пароля відключене. Будь ласка, зв'яжіться з адміністратором сайту.
|
||||||
|
|
||||||
[mail]
|
[mail]
|
||||||
|
|
@ -247,6 +261,8 @@ TreeName=Шлях до файлу
|
||||||
Content=Зміст
|
Content=Зміст
|
||||||
|
|
||||||
require_error=` не може бути пустим.`
|
require_error=` не може бути пустим.`
|
||||||
|
alpha_dash_error=` повинен містити тільки літерно-цифрові символи, дефіс ('-') та підкреслення ('_'). `
|
||||||
|
alpha_dash_dot_error=` повинен містити тільки літерно-цифрові символи, дефіс ('-') , підкреслення ('_') та точки ('.'). `
|
||||||
git_ref_name_error=` повинен бути правильним посилальним ім'ям Git.`
|
git_ref_name_error=` повинен бути правильним посилальним ім'ям Git.`
|
||||||
size_error=` повинен бути розмір %s.`
|
size_error=` повинен бути розмір %s.`
|
||||||
min_size_error=` повинен бути принаймні %s символів.`
|
min_size_error=` повинен бути принаймні %s символів.`
|
||||||
|
|
@ -262,32 +278,39 @@ username_been_taken=Ім'я користувача вже зайнято.
|
||||||
repo_name_been_taken=Ім'я репозіторію вже використовується.
|
repo_name_been_taken=Ім'я репозіторію вже використовується.
|
||||||
org_name_been_taken=Назва організації вже зайнято.
|
org_name_been_taken=Назва організації вже зайнято.
|
||||||
team_name_been_taken=Назва команди вже зайнято.
|
team_name_been_taken=Назва команди вже зайнято.
|
||||||
|
team_no_units_error=Дозволити доступ до принаймні одного розділу репозитарію.
|
||||||
email_been_used=Ця електронна адреса вже використовується.
|
email_been_used=Ця електронна адреса вже використовується.
|
||||||
openid_been_used=OpenID адреса '%s' вже використовується.
|
openid_been_used=OpenID адреса '%s' вже використовується.
|
||||||
username_password_incorrect=Неправильне ім'я користувача або пароль.
|
username_password_incorrect=Неправильне ім'я користувача або пароль.
|
||||||
enterred_invalid_repo_name=Невірно введено ім'я репозиторію.
|
enterred_invalid_repo_name=Невірно введено ім'я репозиторію.
|
||||||
|
enterred_invalid_owner_name=Ім'я нового власника не є дійсним.
|
||||||
|
enterred_invalid_password=Введений вами пароль некоректний.
|
||||||
user_not_exist=Даний користувач не існує.
|
user_not_exist=Даний користувач не існує.
|
||||||
|
last_org_owner=Ви не можете вилучити останнього користувача з команди 'власники'. У кожній команді має бути хоча б один власник.
|
||||||
cannot_add_org_to_team=Організацію неможливо додати як учасника команди.
|
cannot_add_org_to_team=Організацію неможливо додати як учасника команди.
|
||||||
|
|
||||||
invalid_ssh_key=Неможливо перевірити ваш SSH ключ: %s
|
invalid_ssh_key=Неможливо перевірити ваш SSH ключ: %s
|
||||||
invalid_gpg_key=Неможливо перевірити ваш GPG ключ: %s
|
invalid_gpg_key=Неможливо перевірити ваш GPG ключ: %s
|
||||||
|
unable_verify_ssh_key=Не вдається підтвердити ключ SSH; подвійно перевірте його на наявність похибки.
|
||||||
auth_failed=Помилка автентифікації: %v
|
auth_failed=Помилка автентифікації: %v
|
||||||
|
|
||||||
|
still_own_repo=Ваш обліковий запис володіє одним або декількома репозиторіями; видаліть або перенесіть їх в першу чергу.
|
||||||
|
|
||||||
target_branch_not_exist=Цільової гілки не існує.
|
target_branch_not_exist=Цільової гілки не існує.
|
||||||
|
|
||||||
[user]
|
[user]
|
||||||
change_avatar=Змінити свій аватар…
|
change_avatar=Змінити свій аватар…
|
||||||
join_on=Приєднався
|
join_on=Приєднався(-лась)
|
||||||
repositories=Репозиторії
|
repositories=Репозиторії
|
||||||
activity=Публічна активність
|
activity=Публічна активність
|
||||||
followers=Підписники
|
followers=Читачі
|
||||||
starred=Обрані Репозиторії
|
starred=Обрані Репозиторії
|
||||||
following=Слідкувати
|
following=Читає
|
||||||
follow=Підписатися
|
follow=Підписатися
|
||||||
unfollow=Відписатися
|
unfollow=Відписатися
|
||||||
|
|
||||||
form.name_reserved=Ім'я користувача "%s" зарезервовано.
|
form.name_reserved=Ім'я користувача "%s" зарезервовано.
|
||||||
|
form.name_pattern_not_allowed=Шаблон '%s' не дозволено в імені користувача.
|
||||||
|
|
||||||
[settings]
|
[settings]
|
||||||
profile=Профіль
|
profile=Профіль
|
||||||
|
|
@ -309,6 +332,7 @@ u2f=Ключі безпеки
|
||||||
|
|
||||||
public_profile=Загальнодоступний профіль
|
public_profile=Загальнодоступний профіль
|
||||||
profile_desc=Ваша адреса електронної пошти використовуватиметься для сповіщення та інших операцій.
|
profile_desc=Ваша адреса електронної пошти використовуватиметься для сповіщення та інших операцій.
|
||||||
|
password_username_disabled=Нелокальним користувачам заборонено змінювати ім'я користувача. Щоб отримати докладнішу інформацію, зв'яжіться з адміністратором сайту.
|
||||||
full_name=Повне ім'я
|
full_name=Повне ім'я
|
||||||
website=Веб-сайт
|
website=Веб-сайт
|
||||||
location=Місцезнаходження
|
location=Місцезнаходження
|
||||||
|
|
@ -316,7 +340,7 @@ update_profile=Оновити профіль
|
||||||
update_profile_success=Профіль успішно оновлено.
|
update_profile_success=Профіль успішно оновлено.
|
||||||
change_username=Ваше Ім'я кристувача було змінено.
|
change_username=Ваше Ім'я кристувача було змінено.
|
||||||
continue=Продовжити
|
continue=Продовжити
|
||||||
cancel=Відміна
|
cancel=Відмінити
|
||||||
language=Мова
|
language=Мова
|
||||||
|
|
||||||
lookup_avatar_by_mail=Знайти Аватар за адресою електронної пошти
|
lookup_avatar_by_mail=Знайти Аватар за адресою електронної пошти
|
||||||
|
|
@ -338,28 +362,36 @@ password_change_disabled=Нелокальні акаунти не можуть
|
||||||
|
|
||||||
emails=Адреса електронної пошти
|
emails=Адреса електронної пошти
|
||||||
manage_emails=Керування адресами ел. пошти
|
manage_emails=Керування адресами ел. пошти
|
||||||
|
manage_openid=Керування OpenID
|
||||||
email_desc=Ваша основна адреса електронної пошти використовуватиметься для сповіщення та інших операцій.
|
email_desc=Ваша основна адреса електронної пошти використовуватиметься для сповіщення та інших операцій.
|
||||||
primary=Основний
|
primary=Основний
|
||||||
primary_email=Зробити основним
|
primary_email=Зробити основним
|
||||||
delete_email=Видалити
|
delete_email=Видалити
|
||||||
email_deletion=Видалити адресу електронної пошти
|
email_deletion=Видалити адресу електронної пошти
|
||||||
openid_deletion=Видалити адресу OpenID
|
openid_deletion=Видалити адресу OpenID
|
||||||
|
openid_deletion_success=Адреса OpenID була видалена.
|
||||||
add_new_email=Додати нову адресу електронної пошти
|
add_new_email=Додати нову адресу електронної пошти
|
||||||
add_new_openid=Додати новий OpenID URI
|
add_new_openid=Додати новий OpenID URI
|
||||||
add_email=Додати адресу електронної пошти
|
add_email=Додати адресу електронної пошти
|
||||||
add_openid=Додати OpenID URI
|
add_openid=Додати OpenID URI
|
||||||
add_email_confirmation_sent=Електронний лист із підтвердженням було відправлено на '%s', будь ласка, перевірте вашу поштову скриньку протягом наступних %s, щоб підтвердити адресу.
|
add_email_confirmation_sent=Електронний лист із підтвердженням було відправлено на '%s', будь ласка, перевірте вашу поштову скриньку протягом наступних %s, щоб підтвердити адресу.
|
||||||
add_email_success=Додано нову адресу електронної пошти.
|
add_email_success=Додано нову адресу електронної пошти.
|
||||||
|
add_openid_success=Нова адреса OpenID була додана.
|
||||||
keep_email_private=Приховати адресу електронної пошти
|
keep_email_private=Приховати адресу електронної пошти
|
||||||
keep_email_private_popup=Вашу адресу електронної пошти буде приховано від інших користувачів.
|
keep_email_private_popup=Вашу адресу електронної пошти буде приховано від інших користувачів.
|
||||||
|
|
||||||
manage_ssh_keys=Керувати SSH ключами
|
manage_ssh_keys=Керувати SSH ключами
|
||||||
manage_gpg_keys=Керувати GPG ключами
|
manage_gpg_keys=Керувати GPG ключами
|
||||||
add_key=Додати ключ
|
add_key=Додати ключ
|
||||||
|
ssh_desc=Ці відкриті SSH-ключі пов'язані з вашим обліковим записом. Відповідні приватні ключі дозволяють отримати повний доступ до ваших репозиторіїв.
|
||||||
|
gpg_desc=Ці публічні ключі GPG пов'язані з вашим обліковим записом. Тримайте свої приватні ключі в безпеці, оскільки вони дозволяють здійснювати перевірку комітів.
|
||||||
ssh_helper=<strong>Потрібна допомога?</strong> Дивіться гід на GitHub з <a href="%s"> генерації ключів SSH</a> або виправлення <a href="%s">типових неполадок SSH</a>.
|
ssh_helper=<strong>Потрібна допомога?</strong> Дивіться гід на GitHub з <a href="%s"> генерації ключів SSH</a> або виправлення <a href="%s">типових неполадок SSH</a>.
|
||||||
gpg_helper=<strong> Потрібна допомога? </strong> Перегляньте посібник GitHub <a href="%s"> про GPG </a>.
|
gpg_helper=<strong> Потрібна допомога? </strong> Перегляньте посібник GitHub <a href="%s"> про GPG </a>.
|
||||||
add_new_key=Додати SSH ключ
|
add_new_key=Додати SSH ключ
|
||||||
add_new_gpg_key=Додати GPG ключ
|
add_new_gpg_key=Додати GPG ключ
|
||||||
|
ssh_key_been_used=Цей ключ SSH вже додано до вашого облікового запису.
|
||||||
|
ssh_key_name_used=Ключ SSH з таким самим ім'ям вже додано до вашого облікового запису.
|
||||||
|
gpg_key_id_used=Публічний ключ GPG з таким самим ідентифікатором вже існує.
|
||||||
subkeys=Підключі
|
subkeys=Підключі
|
||||||
key_id=ID ключа
|
key_id=ID ключа
|
||||||
key_name=Ім'я ключа
|
key_name=Ім'я ключа
|
||||||
|
|
@ -397,15 +429,26 @@ generate_token=Згенерувати токен
|
||||||
delete_token=Видалити
|
delete_token=Видалити
|
||||||
access_token_deletion=Видалити токен доступу
|
access_token_deletion=Видалити токен доступу
|
||||||
|
|
||||||
|
twofa_desc=Двофакторна автентифікація підвищує безпеку вашого облікового запису.
|
||||||
|
twofa_is_enrolled=Ваш обліковий запис на даний час <strong>використовує</strong> двофакторну автентифікацію.
|
||||||
|
twofa_not_enrolled=Ваш обліковий запис наразі не використовує двофакторну автентифікаціїю.
|
||||||
twofa_disable=Вимкнути двофакторну автентифікацію
|
twofa_disable=Вимкнути двофакторну автентифікацію
|
||||||
|
twofa_scratch_token_regenerate=Перестворити токен одноразового пароля
|
||||||
|
twofa_enroll=Увімкнути двофакторну автентифікацію
|
||||||
|
twofa_disable_note=При необхідності можна відключити двофакторну автентифікацію.
|
||||||
|
regenerate_scratch_token_desc=Якщо ви втратили свій токен одноразового пароля або вже використовували його для входу, ви можете скинути його тут.
|
||||||
|
twofa_disabled=Двофакторна автентифікація вимкнена.
|
||||||
|
scan_this_image=Проскануйте це зображення вашим додатком для двуфакторної автентифікації:
|
||||||
or_enter_secret=Або введіть секрет: %s
|
or_enter_secret=Або введіть секрет: %s
|
||||||
passcode_invalid=Некоректний пароль. Спробуй ще раз.
|
passcode_invalid=Некоректний пароль. Спробуй ще раз.
|
||||||
|
|
||||||
|
u2f_desc=Ключами безпеки є апаратні пристрої, що містять криптографічні ключі. Вони можуть використовуватися для двофакторної автентифікації. Ключ безпеки повинен підтримувати стандарт <a href="https://fidoalliance.org/">FIDO U2F</a>.
|
||||||
u2f_register_key=Додати ключ безпеки
|
u2f_register_key=Додати ключ безпеки
|
||||||
u2f_nickname=Псевдонім
|
u2f_nickname=Псевдонім
|
||||||
u2f_delete_key=Видалити ключ безпеки
|
u2f_delete_key=Видалити ключ безпеки
|
||||||
|
|
||||||
manage_account_links=Керування обліковими записами
|
manage_account_links=Керування обліковими записами
|
||||||
|
manage_account_links_desc=Ці зовнішні акаунти прив'язані до вашого аккаунту Gitea.
|
||||||
remove_account_link=Видалити облікові записи
|
remove_account_link=Видалити облікові записи
|
||||||
|
|
||||||
orgs_none=Ви не є учасником будь-якої організації.
|
orgs_none=Ви не є учасником будь-якої організації.
|
||||||
|
|
@ -421,6 +464,7 @@ owner=Власник
|
||||||
repo_name=Назва репозиторію
|
repo_name=Назва репозиторію
|
||||||
visibility=Видимість
|
visibility=Видимість
|
||||||
visiblity_helper=Зробити репозиторій приватним
|
visiblity_helper=Зробити репозиторій приватним
|
||||||
|
visiblity_fork_helper=(Зміна цього вплине на всі форки.)
|
||||||
clone_helper=Потрібна допомога у клонуванні? Відвідайте <a target="_blank" rel="noopener" href="%s">Допомогу</a>.
|
clone_helper=Потрібна допомога у клонуванні? Відвідайте <a target="_blank" rel="noopener" href="%s">Допомогу</a>.
|
||||||
fork_repo=Форкнути репозиторій
|
fork_repo=Форкнути репозиторій
|
||||||
fork_from=Форк з
|
fork_from=Форк з
|
||||||
|
|
@ -432,6 +476,7 @@ license=Ліцензія
|
||||||
license_helper=Виберіть ліцензійний файл.
|
license_helper=Виберіть ліцензійний файл.
|
||||||
readme=README
|
readme=README
|
||||||
readme_helper=Виберіть шаблон README.
|
readme_helper=Виберіть шаблон README.
|
||||||
|
auto_init=Ініціалізувати репозиторій (Додає .gitignore, LICENSE та README)
|
||||||
create_repo=Створити репозиторій
|
create_repo=Створити репозиторій
|
||||||
default_branch=Головна гілка
|
default_branch=Головна гілка
|
||||||
mirror_prune=Очистити
|
mirror_prune=Очистити
|
||||||
|
|
@ -525,7 +570,7 @@ editor.commit_message_desc=Додати необов'язковий розшир
|
||||||
editor.commit_directly_to_this_branch=Зробіть коміт прямо в гілку <strong class="branch-name">%s</strong>.
|
editor.commit_directly_to_this_branch=Зробіть коміт прямо в гілку <strong class="branch-name">%s</strong>.
|
||||||
editor.create_new_branch=Створити <strong>нову гілку</strong> для цього коміту та відкрити запит на злиття.
|
editor.create_new_branch=Створити <strong>нову гілку</strong> для цього коміту та відкрити запит на злиття.
|
||||||
editor.new_branch_name_desc=Ім'я нової гілки…
|
editor.new_branch_name_desc=Ім'я нової гілки…
|
||||||
editor.cancel=Відміна
|
editor.cancel=Відмінити
|
||||||
editor.filename_cannot_be_empty=Ім'я файлу не може бути порожнім.
|
editor.filename_cannot_be_empty=Ім'я файлу не може бути порожнім.
|
||||||
editor.branch_already_exists=Гілка '%s' вже присутня в репозиторії.
|
editor.branch_already_exists=Гілка '%s' вже присутня в репозиторії.
|
||||||
editor.directory_is_a_file=Ім'я каталогу "%s" уже використовується як ім'я файлу в цьому репозиторії.
|
editor.directory_is_a_file=Ім'я каталогу "%s" уже використовується як ім'я файлу в цьому репозиторії.
|
||||||
|
|
@ -546,8 +591,10 @@ commits.date=Дата
|
||||||
commits.older=Давніше
|
commits.older=Давніше
|
||||||
commits.newer=Новіше
|
commits.newer=Новіше
|
||||||
commits.signed_by=Підписано
|
commits.signed_by=Підписано
|
||||||
|
commits.gpg_key_id=Ідентифікатор GPG ключа
|
||||||
|
|
||||||
ext_issues=Зов. Проблеми
|
ext_issues=Зов. Проблеми
|
||||||
|
ext_issues.desc=Посилання на зовнішню систему відстеження проблем.
|
||||||
|
|
||||||
issues.new=Нова проблема
|
issues.new=Нова проблема
|
||||||
issues.new.labels=Мітки
|
issues.new.labels=Мітки
|
||||||
|
|
@ -569,6 +616,7 @@ issues.new_label_desc_placeholder=Опис
|
||||||
issues.create_label=Створити мітку
|
issues.create_label=Створити мітку
|
||||||
issues.label_templates.title=Завантажити визначений набір міток
|
issues.label_templates.title=Завантажити визначений набір міток
|
||||||
issues.label_templates.helper=Оберіть набір міток
|
issues.label_templates.helper=Оберіть набір міток
|
||||||
|
issues.label_templates.use=Використовувати набір міток
|
||||||
issues.label_templates.fail_to_load_file=Не вдалося завантажити файл шаблона мітки '%s': %v
|
issues.label_templates.fail_to_load_file=Не вдалося завантажити файл шаблона мітки '%s': %v
|
||||||
issues.add_label_at=додав(ла) мітку <div class="ui label" style="color: %s\; background-color: %s">%s</div> %s
|
issues.add_label_at=додав(ла) мітку <div class="ui label" style="color: %s\; background-color: %s">%s</div> %s
|
||||||
issues.add_milestone_at=`додав(ла) до <b>%s</b> етапу %s`
|
issues.add_milestone_at=`додав(ла) до <b>%s</b> етапу %s`
|
||||||
|
|
@ -596,7 +644,10 @@ issues.filter_sort.recentupdate=Нещодавно оновлено
|
||||||
issues.filter_sort.leastupdate=Найдавніше оновлені
|
issues.filter_sort.leastupdate=Найдавніше оновлені
|
||||||
issues.filter_sort.mostcomment=Найбільш коментовані
|
issues.filter_sort.mostcomment=Найбільш коментовані
|
||||||
issues.filter_sort.leastcomment=Найменш коментовані
|
issues.filter_sort.leastcomment=Найменш коментовані
|
||||||
|
issues.filter_sort.moststars=Найбільш обраних
|
||||||
|
issues.filter_sort.feweststars=Найменш обраних
|
||||||
issues.filter_sort.mostforks=Найбільше форків
|
issues.filter_sort.mostforks=Найбільше форків
|
||||||
|
issues.filter_sort.fewestforks=Найменше форків
|
||||||
issues.action_open=Відкрити
|
issues.action_open=Відкрити
|
||||||
issues.action_close=Закрити
|
issues.action_close=Закрити
|
||||||
issues.action_label=Мітка
|
issues.action_label=Мітка
|
||||||
|
|
@ -627,7 +678,7 @@ issues.collaborator=Співавтор
|
||||||
issues.owner=Власник
|
issues.owner=Власник
|
||||||
issues.sign_in_require_desc=<a href="%s">Підпишіться</a> щоб приєднатися до обговорення.
|
issues.sign_in_require_desc=<a href="%s">Підпишіться</a> щоб приєднатися до обговорення.
|
||||||
issues.edit=Редагувати
|
issues.edit=Редагувати
|
||||||
issues.cancel=Відміна
|
issues.cancel=Відмінити
|
||||||
issues.save=Зберегти
|
issues.save=Зберегти
|
||||||
issues.label_title=Назва мітки
|
issues.label_title=Назва мітки
|
||||||
issues.label_description=Опис мітки
|
issues.label_description=Опис мітки
|
||||||
|
|
@ -654,17 +705,21 @@ issues.start_tracking=Почати відстеження часу
|
||||||
issues.start_tracking_history=`почав працювати %s`
|
issues.start_tracking_history=`почав працювати %s`
|
||||||
issues.tracking_already_started=`Ви вже почали відстежувати час для цієї <a href="%s"> проблеми</a>!`
|
issues.tracking_already_started=`Ви вже почали відстежувати час для цієї <a href="%s"> проблеми</a>!`
|
||||||
issues.stop_tracking=Стоп
|
issues.stop_tracking=Стоп
|
||||||
|
issues.stop_tracking_history=`перестав(-ла) працювати %s`
|
||||||
issues.add_time=Вручну додати час
|
issues.add_time=Вручну додати час
|
||||||
issues.add_time_short=Додати час
|
issues.add_time_short=Додати час
|
||||||
issues.add_time_cancel=Відміна
|
issues.add_time_cancel=Відмінити
|
||||||
|
issues.add_time_history=`додав(-ла) витрачений час %s`
|
||||||
issues.add_time_hours=Години
|
issues.add_time_hours=Години
|
||||||
issues.add_time_minutes=Хвилини
|
issues.add_time_minutes=Хвилини
|
||||||
issues.add_time_sum_to_small=Час не введено.
|
issues.add_time_sum_to_small=Час не введено.
|
||||||
issues.cancel_tracking=Відміна
|
issues.cancel_tracking=Відмінити
|
||||||
issues.cancel_tracking_history=`скасував відстеження часу %s`
|
issues.cancel_tracking_history=`скасував відстеження часу %s`
|
||||||
issues.time_spent_total=Загальний витрачений час
|
issues.time_spent_total=Загальний витрачений час
|
||||||
issues.time_spent_from_all_authors=`Загальний витрачений час: %s`
|
issues.time_spent_from_all_authors=`Загальний витрачений час: %s`
|
||||||
issues.due_date=Дата завершення
|
issues.due_date=Дата завершення
|
||||||
|
issues.invalid_due_date_format=Дата закінчення має бути в форматі 'ррр-мм-дд'.
|
||||||
|
issues.error_modifying_due_date=Не вдалося змінити дату завершення.
|
||||||
issues.due_date_form=рррр-мм-дд
|
issues.due_date_form=рррр-мм-дд
|
||||||
issues.due_date_form_add=Додати дату завершення
|
issues.due_date_form_add=Додати дату завершення
|
||||||
issues.due_date_form_update=Оновити дату завершення
|
issues.due_date_form_update=Оновити дату завершення
|
||||||
|
|
@ -711,13 +766,16 @@ milestones.desc=Опис
|
||||||
milestones.due_date=Дата завершення (опціонально)
|
milestones.due_date=Дата завершення (опціонально)
|
||||||
milestones.clear=Очистити
|
milestones.clear=Очистити
|
||||||
milestones.edit=Редагувати етап
|
milestones.edit=Редагувати етап
|
||||||
milestones.cancel=Відміна
|
milestones.cancel=Відмінити
|
||||||
milestones.modify=Оновити етап
|
milestones.modify=Оновити етап
|
||||||
milestones.deletion=Видалити етап
|
milestones.deletion=Видалити етап
|
||||||
|
milestones.filter_sort.closest_due_date=Найближче за датою
|
||||||
|
milestones.filter_sort.furthest_due_date=Далі за датою
|
||||||
milestones.filter_sort.most_issues=Найбільш проблем
|
milestones.filter_sort.most_issues=Найбільш проблем
|
||||||
milestones.filter_sort.least_issues=Найменш проблем
|
milestones.filter_sort.least_issues=Найменш проблем
|
||||||
|
|
||||||
ext_wiki=Зов. Вікі
|
ext_wiki=Зов. Вікі
|
||||||
|
ext_wiki.desc=Посилання на зовнішню вікі.
|
||||||
|
|
||||||
wiki=Вікі
|
wiki=Вікі
|
||||||
wiki.welcome=Ласкаво просимо до Вікі.
|
wiki.welcome=Ласкаво просимо до Вікі.
|
||||||
|
|
@ -767,6 +825,7 @@ activity.closed_issue_label=Закрито
|
||||||
activity.new_issues_count_1=Нова Проблема
|
activity.new_issues_count_1=Нова Проблема
|
||||||
activity.new_issues_count_n=%d Проблем
|
activity.new_issues_count_n=%d Проблем
|
||||||
activity.new_issue_label=Відкриті
|
activity.new_issue_label=Відкриті
|
||||||
|
activity.title.unresolved_conv_1=%d Незавершене обговорення
|
||||||
activity.unresolved_conv_label=Відкрити
|
activity.unresolved_conv_label=Відкрити
|
||||||
activity.title.releases_1=%d Реліз
|
activity.title.releases_1=%d Реліз
|
||||||
activity.title.releases_n=%d Релізів
|
activity.title.releases_n=%d Релізів
|
||||||
|
|
@ -932,7 +991,7 @@ release.preview=Переглянути
|
||||||
release.loading=Завантаження…
|
release.loading=Завантаження…
|
||||||
release.prerelease_desc=Позначити як пре-реліз
|
release.prerelease_desc=Позначити як пре-реліз
|
||||||
release.prerelease_helper=Позначте цей випуск непридатним для ПРОД використання.
|
release.prerelease_helper=Позначте цей випуск непридатним для ПРОД використання.
|
||||||
release.cancel=Відміна
|
release.cancel=Відмінити
|
||||||
release.publish=Опублікувати реліз
|
release.publish=Опублікувати реліз
|
||||||
release.save_draft=Зберегти чернетку
|
release.save_draft=Зберегти чернетку
|
||||||
release.edit_release=Оновити реліз
|
release.edit_release=Оновити реліз
|
||||||
|
|
@ -961,6 +1020,7 @@ topic.done=Готово
|
||||||
[org]
|
[org]
|
||||||
org_name_holder=Назва організації
|
org_name_holder=Назва організації
|
||||||
org_full_name_holder=Повна назва організації
|
org_full_name_holder=Повна назва організації
|
||||||
|
org_name_helper=Назва організації має бути простою та зрозумілою.
|
||||||
create_org=Створити організацію
|
create_org=Створити організацію
|
||||||
repo_updated=Оновлено
|
repo_updated=Оновлено
|
||||||
people=Учасники
|
people=Учасники
|
||||||
|
|
@ -1089,7 +1149,9 @@ users.admin=Адміністратор
|
||||||
users.repos=Репозиторії
|
users.repos=Репозиторії
|
||||||
users.created=Створено
|
users.created=Створено
|
||||||
users.last_login=Останній вхід
|
users.last_login=Останній вхід
|
||||||
|
users.never_login=Ніколи не входив
|
||||||
users.send_register_notify=Надіслати повідомлення про реєстрацію користувача
|
users.send_register_notify=Надіслати повідомлення про реєстрацію користувача
|
||||||
|
users.new_success=Обліковий запис '%s' створений.
|
||||||
users.edit=Редагувати
|
users.edit=Редагувати
|
||||||
users.auth_source=Джерело автентифікації
|
users.auth_source=Джерело автентифікації
|
||||||
users.local=Локальні
|
users.local=Локальні
|
||||||
|
|
@ -1123,7 +1185,7 @@ repos.forks=Форки
|
||||||
repos.issues=Проблеми
|
repos.issues=Проблеми
|
||||||
repos.size=Розмір
|
repos.size=Розмір
|
||||||
|
|
||||||
auths.auth_manage_panel=Керування джерелом аутентифікації
|
auths.auth_manage_panel=Керування джерелом автентифікації
|
||||||
auths.new=Додати джерело автентифікації
|
auths.new=Додати джерело автентифікації
|
||||||
auths.name=Ім'я
|
auths.name=Ім'я
|
||||||
auths.type=Тип
|
auths.type=Тип
|
||||||
|
|
@ -1160,8 +1222,8 @@ auths.oauth2_profileURL=URL профілю
|
||||||
auths.oauth2_emailURL=URL електронної пошти
|
auths.oauth2_emailURL=URL електронної пошти
|
||||||
auths.enable_auto_register=Увімкнути автоматичну реєстрацію
|
auths.enable_auto_register=Увімкнути автоматичну реєстрацію
|
||||||
auths.tips=Поради
|
auths.tips=Поради
|
||||||
auths.tips.oauth2.general=OAuth2 аутентифікація
|
auths.tips.oauth2.general=OAuth2 автентифікація
|
||||||
auths.tips.oauth2.general.tip=При додаванні нового OAuth2 провайдера, URL адреса переадресації по завершенні аутентифікації повинена виглядати так:<host>/user/oauth2/<Authentication Name>/callback
|
auths.tips.oauth2.general.tip=При додаванні нового OAuth2 провайдера, URL адреса переадресації по завершенні автентифікації повинена виглядати так:<host>/user/oauth2/<Authentication Name>/callback
|
||||||
auths.tip.oauth2_provider=Постачальник OAuth2
|
auths.tip.oauth2_provider=Постачальник OAuth2
|
||||||
auths.tip.dropbox=Додайте новий додаток на https://www.dropbox.com/developers/apps
|
auths.tip.dropbox=Додайте новий додаток на https://www.dropbox.com/developers/apps
|
||||||
auths.tip.facebook=Створіть новий додаток на https://developers.facebook.com/apps і додайте модуль "Facebook Login
|
auths.tip.facebook=Створіть новий додаток на https://developers.facebook.com/apps і додайте модуль "Facebook Login
|
||||||
|
|
@ -1225,6 +1287,7 @@ config.default_keep_email_private=Приховати адресу електро
|
||||||
config.default_allow_create_organization=Дозволити створення організацій за замовчуванням
|
config.default_allow_create_organization=Дозволити створення організацій за замовчуванням
|
||||||
config.enable_timetracking=Увімкнути відстеження часу
|
config.enable_timetracking=Увімкнути відстеження часу
|
||||||
config.default_enable_timetracking=Увімкнути відстеження часу за замовчуванням
|
config.default_enable_timetracking=Увімкнути відстеження часу за замовчуванням
|
||||||
|
config.no_reply_address=Прихований домен електронної пошти
|
||||||
|
|
||||||
config.webhook_config=Конфігурація web-хуків
|
config.webhook_config=Конфігурація web-хуків
|
||||||
config.queue_length=Довжина черги
|
config.queue_length=Довжина черги
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ send_reset_mail=单击此处(重新)发送您的密码重置邮件
|
||||||
reset_password=重置密码
|
reset_password=重置密码
|
||||||
invalid_code=此确认密钥无效或已过期。
|
invalid_code=此确认密钥无效或已过期。
|
||||||
reset_password_helper=单击此处重置密码
|
reset_password_helper=单击此处重置密码
|
||||||
password_too_short=密码长度不能少于 %d 位!
|
password_too_short=密码长度不能少于 %d 位。
|
||||||
non_local_account=非本地帐户不能通过 Gitea 的 web 界面更改密码。
|
non_local_account=非本地帐户不能通过 Gitea 的 web 界面更改密码。
|
||||||
verify=验证
|
verify=验证
|
||||||
scratch_code=验证口令
|
scratch_code=验证口令
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,6 @@ email_not_associate=此電子郵件地址未與任何帳戶連結
|
||||||
send_reset_mail=點選此處重發您的密碼重製郵件
|
send_reset_mail=點選此處重發您的密碼重製郵件
|
||||||
reset_password=重置密碼
|
reset_password=重置密碼
|
||||||
reset_password_helper=單擊此處重置密碼
|
reset_password_helper=單擊此處重置密碼
|
||||||
password_too_short=密碼長度不能少於 %d 位!
|
|
||||||
verify=驗證
|
verify=驗證
|
||||||
scratch_code=備用碼
|
scratch_code=備用碼
|
||||||
use_scratch_code=使用備用碼
|
use_scratch_code=使用備用碼
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,6 @@ email_not_associate=此電子郵件地址未與任何帳戶連結
|
||||||
send_reset_mail=點選此處重發您的密碼重製郵件
|
send_reset_mail=點選此處重發您的密碼重製郵件
|
||||||
reset_password=重置密碼
|
reset_password=重置密碼
|
||||||
reset_password_helper=單擊此處重置密碼
|
reset_password_helper=單擊此處重置密碼
|
||||||
password_too_short=密碼長度不能少於 %d 位!
|
|
||||||
verify=驗證
|
verify=驗證
|
||||||
scratch_code=備用碼
|
scratch_code=備用碼
|
||||||
use_scratch_code=使用備用碼
|
use_scratch_code=使用備用碼
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -2336,8 +2336,10 @@ function initTopicbar() {
|
||||||
}).done(function() {
|
}).done(function() {
|
||||||
editDiv.hide();
|
editDiv.hide();
|
||||||
viewDiv.show();
|
viewDiv.show();
|
||||||
|
}).fail(function(xhr) {
|
||||||
|
alert(xhr.responseJSON.message)
|
||||||
})
|
})
|
||||||
})
|
});
|
||||||
|
|
||||||
$('#topic_edit .dropdown').dropdown({
|
$('#topic_edit .dropdown').dropdown({
|
||||||
allowAdditions: true,
|
allowAdditions: true,
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@
|
||||||
line-height: 1.6 !important;
|
line-height: 1.6 !important;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
|
||||||
|
&.ui.segment {
|
||||||
|
padding: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
&.file-view {
|
&.file-view {
|
||||||
padding: 2em 2em 2em !important;
|
padding: 2em 2em 2em !important;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
494
public/swagger.v1.json
vendored
494
public/swagger.v1.json
vendored
|
|
@ -321,9 +321,13 @@
|
||||||
"operationId": "renderMarkdownRaw",
|
"operationId": "renderMarkdownRaw",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "string",
|
"description": "Request body to render",
|
||||||
"name": "body",
|
"name": "body",
|
||||||
"in": "body"
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
|
|
@ -448,6 +452,15 @@
|
||||||
],
|
],
|
||||||
"summary": "List an organization's webhooks",
|
"summary": "List an organization's webhooks",
|
||||||
"operationId": "orgListHooks",
|
"operationId": "orgListHooks",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the organization",
|
||||||
|
"name": "org",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"$ref": "#/responses/HookList"
|
"$ref": "#/responses/HookList"
|
||||||
|
|
@ -468,6 +481,15 @@
|
||||||
],
|
],
|
||||||
"summary": "Create a hook",
|
"summary": "Create a hook",
|
||||||
"operationId": "orgCreateHook",
|
"operationId": "orgCreateHook",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the organization",
|
||||||
|
"name": "org",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"201": {
|
"201": {
|
||||||
"$ref": "#/responses/Hook"
|
"$ref": "#/responses/Hook"
|
||||||
|
|
@ -485,6 +507,22 @@
|
||||||
],
|
],
|
||||||
"summary": "Get a hook",
|
"summary": "Get a hook",
|
||||||
"operationId": "orgGetHook",
|
"operationId": "orgGetHook",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the organization",
|
||||||
|
"name": "org",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "id of the hook to get",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"$ref": "#/responses/Hook"
|
"$ref": "#/responses/Hook"
|
||||||
|
|
@ -500,6 +538,22 @@
|
||||||
],
|
],
|
||||||
"summary": "Delete a hook",
|
"summary": "Delete a hook",
|
||||||
"operationId": "orgDeleteHook",
|
"operationId": "orgDeleteHook",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the organization",
|
||||||
|
"name": "org",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "id of the hook to delete",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"204": {
|
"204": {
|
||||||
"$ref": "#/responses/empty"
|
"$ref": "#/responses/empty"
|
||||||
|
|
@ -518,6 +572,22 @@
|
||||||
],
|
],
|
||||||
"summary": "Update a hook",
|
"summary": "Update a hook",
|
||||||
"operationId": "orgEditHook",
|
"operationId": "orgEditHook",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the organization",
|
||||||
|
"name": "org",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "id of the hook to update",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"$ref": "#/responses/Hook"
|
"$ref": "#/responses/Hook"
|
||||||
|
|
@ -1006,7 +1076,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/repos/{owner}/{repo}/archive/{filepath}": {
|
"/repos/{owner}/{repo}/archive/{archive}": {
|
||||||
"get": {
|
"get": {
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
|
|
@ -1542,6 +1612,47 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"delete": {
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"repository"
|
||||||
|
],
|
||||||
|
"summary": "Delete a hook in a repository",
|
||||||
|
"operationId": "repoDeleteHook",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "owner of the repo",
|
||||||
|
"name": "owner",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the repo",
|
||||||
|
"name": "repo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "id of the hook to delete",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"$ref": "#/responses/empty"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"$ref": "#/responses/notFound"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"patch": {
|
"patch": {
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
|
|
@ -1566,6 +1677,13 @@
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "index of the hook",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "body",
|
"name": "body",
|
||||||
"in": "body",
|
"in": "body",
|
||||||
|
|
@ -1837,6 +1955,100 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/repos/{owner}/{repo}/issues/{id}/times": {
|
||||||
|
"get": {
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"issue"
|
||||||
|
],
|
||||||
|
"summary": "List an issue's tracked times",
|
||||||
|
"operationId": "issueTrackedTimes",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "owner of the repo",
|
||||||
|
"name": "owner",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the repo",
|
||||||
|
"name": "repo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "index of the issue",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/TrackedTimeList"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"issue"
|
||||||
|
],
|
||||||
|
"summary": "Add a tracked time to a issue",
|
||||||
|
"operationId": "issueAddTime",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "owner of the repo",
|
||||||
|
"name": "owner",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the repo",
|
||||||
|
"name": "repo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "index of the issue to add tracked time to",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/AddTimeOption"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/TrackedTime"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"$ref": "#/responses/error"
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"$ref": "#/responses/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/repos/{owner}/{repo}/issues/{index}": {
|
"/repos/{owner}/{repo}/issues/{index}": {
|
||||||
"get": {
|
"get": {
|
||||||
"produces": [
|
"produces": [
|
||||||
|
|
@ -1953,7 +2165,7 @@
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"description": "index of the issue",
|
"description": "index of the issue",
|
||||||
"name": "id",
|
"name": "index",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
|
|
@ -2000,7 +2212,7 @@
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"description": "index of the issue",
|
"description": "index of the issue",
|
||||||
"name": "id",
|
"name": "index",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
|
|
@ -2008,7 +2220,7 @@
|
||||||
"name": "body",
|
"name": "body",
|
||||||
"in": "body",
|
"in": "body",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/CreateIssueOption"
|
"$ref": "#/definitions/CreateIssueCommentOption"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -2344,100 +2556,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/repos/{owner}/{repo}/issues/{index}/times": {
|
|
||||||
"get": {
|
|
||||||
"produces": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"issue"
|
|
||||||
],
|
|
||||||
"summary": "List an issue's tracked times",
|
|
||||||
"operationId": "issueTrackedTimes",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "owner of the repo",
|
|
||||||
"name": "owner",
|
|
||||||
"in": "path",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "name of the repo",
|
|
||||||
"name": "repo",
|
|
||||||
"in": "path",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "integer",
|
|
||||||
"description": "index of the issue",
|
|
||||||
"name": "repo",
|
|
||||||
"in": "path",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"$ref": "#/responses/TrackedTimeList"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"post": {
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"produces": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"issue"
|
|
||||||
],
|
|
||||||
"summary": "Add a tracked time to a issue",
|
|
||||||
"operationId": "issueAddTime",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "owner of the repo",
|
|
||||||
"name": "owner",
|
|
||||||
"in": "path",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "name of the repo",
|
|
||||||
"name": "repo",
|
|
||||||
"in": "path",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "integer",
|
|
||||||
"description": "index of the issue to add tracked time to",
|
|
||||||
"name": "id",
|
|
||||||
"in": "path",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "body",
|
|
||||||
"in": "body",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/AddTimeOption"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"$ref": "#/responses/TrackedTime"
|
|
||||||
},
|
|
||||||
"400": {
|
|
||||||
"$ref": "#/responses/error"
|
|
||||||
},
|
|
||||||
"403": {
|
|
||||||
"$ref": "#/responses/error"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/repos/{owner}/{repo}/keys": {
|
"/repos/{owner}/{repo}/keys": {
|
||||||
"get": {
|
"get": {
|
||||||
"produces": [
|
"produces": [
|
||||||
|
|
@ -2793,7 +2911,7 @@
|
||||||
"issue"
|
"issue"
|
||||||
],
|
],
|
||||||
"summary": "Get all of a repository's milestones",
|
"summary": "Get all of a repository's milestones",
|
||||||
"operationId": "issueGetMilestones",
|
"operationId": "issueGetMilestonesList",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|
@ -2808,13 +2926,6 @@
|
||||||
"name": "repo",
|
"name": "repo",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "integer",
|
|
||||||
"description": "id of the milestone to get",
|
|
||||||
"name": "id",
|
|
||||||
"in": "path",
|
|
||||||
"required": true
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
|
|
@ -2875,6 +2986,29 @@
|
||||||
],
|
],
|
||||||
"summary": "Get a milestone",
|
"summary": "Get a milestone",
|
||||||
"operationId": "issueGetMilestone",
|
"operationId": "issueGetMilestone",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "owner of the repo",
|
||||||
|
"name": "owner",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the repo",
|
||||||
|
"name": "repo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "id of the milestone",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"$ref": "#/responses/Milestone"
|
"$ref": "#/responses/Milestone"
|
||||||
|
|
@ -2905,7 +3039,7 @@
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"description": "id of the milestone to delete",
|
"description": "id of the milestone to delete",
|
||||||
"name": "body",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
}
|
}
|
||||||
|
|
@ -2943,6 +3077,13 @@
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "id of the milestone",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "body",
|
"name": "body",
|
||||||
"in": "body",
|
"in": "body",
|
||||||
|
|
@ -3991,7 +4132,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/repos/{owner}/{repo}/times/{tracker}": {
|
"/repos/{owner}/{repo}/times/{user}": {
|
||||||
"get": {
|
"get": {
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
|
|
@ -4031,49 +4172,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/repos/{user}/{repo}/hooks/{id}": {
|
|
||||||
"delete": {
|
|
||||||
"produces": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"repository"
|
|
||||||
],
|
|
||||||
"summary": "Delete a hook in a repository",
|
|
||||||
"operationId": "repoDeleteHook",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "owner of the repo",
|
|
||||||
"name": "owner",
|
|
||||||
"in": "path",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "name of the repo",
|
|
||||||
"name": "repo",
|
|
||||||
"in": "path",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "integer",
|
|
||||||
"description": "id of the hook to delete",
|
|
||||||
"name": "id",
|
|
||||||
"in": "path",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"204": {
|
|
||||||
"$ref": "#/responses/empty"
|
|
||||||
},
|
|
||||||
"404": {
|
|
||||||
"$ref": "#/responses/notFound"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/repositories/{id}": {
|
"/repositories/{id}": {
|
||||||
"get": {
|
"get": {
|
||||||
"produces": [
|
"produces": [
|
||||||
|
|
@ -4250,7 +4348,7 @@
|
||||||
"organization"
|
"organization"
|
||||||
],
|
],
|
||||||
"summary": "Remove a team member",
|
"summary": "Remove a team member",
|
||||||
"operationId": "orgAddTeamMember",
|
"operationId": "orgRemoveTeamMember",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
|
|
@ -4309,7 +4407,7 @@
|
||||||
"organization"
|
"organization"
|
||||||
],
|
],
|
||||||
"summary": "Add a repository to a team",
|
"summary": "Add a repository to a team",
|
||||||
"operationId": "orgAddTeamMember",
|
"operationId": "orgAddTeamRepository",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
|
|
@ -4348,7 +4446,7 @@
|
||||||
"organization"
|
"organization"
|
||||||
],
|
],
|
||||||
"summary": "Remove a repository from a team",
|
"summary": "Remove a repository from a team",
|
||||||
"operationId": "orgAddTeamMember",
|
"operationId": "orgRemoveTeamRepository",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
|
|
@ -4391,10 +4489,10 @@
|
||||||
"operationId": "topicSearch",
|
"operationId": "topicSearch",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "string",
|
||||||
"description": "id of the repo to get",
|
"description": "keywords to search",
|
||||||
"name": "keyword",
|
"name": "q",
|
||||||
"in": "path",
|
"in": "query",
|
||||||
"required": true
|
"required": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -4521,7 +4619,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/user/following/{followee}": {
|
"/user/following/{username}": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"user"
|
"user"
|
||||||
|
|
@ -4532,7 +4630,7 @@
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "username of followed user",
|
"description": "username of followed user",
|
||||||
"name": "followee",
|
"name": "username",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
}
|
}
|
||||||
|
|
@ -4545,9 +4643,7 @@
|
||||||
"$ref": "#/responses/notFound"
|
"$ref": "#/responses/notFound"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
|
||||||
"/user/following/{username}": {
|
|
||||||
"put": {
|
"put": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"user"
|
"user"
|
||||||
|
|
@ -5313,6 +5409,15 @@
|
||||||
],
|
],
|
||||||
"summary": "List the authenticated user's access tokens",
|
"summary": "List the authenticated user's access tokens",
|
||||||
"operationId": "userGetTokens",
|
"operationId": "userGetTokens",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "username of user",
|
||||||
|
"name": "username",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"$ref": "#/responses/AccessTokenList"
|
"$ref": "#/responses/AccessTokenList"
|
||||||
|
|
@ -5335,8 +5440,10 @@
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Name",
|
"x-go-name": "Name",
|
||||||
"name": "name",
|
"description": "username of user",
|
||||||
"in": "query"
|
"name": "username",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
|
|
@ -7624,9 +7731,6 @@
|
||||||
"description": "SearchResults",
|
"description": "SearchResults",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/SearchResults"
|
"$ref": "#/definitions/SearchResults"
|
||||||
},
|
|
||||||
"headers": {
|
|
||||||
"body": {}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ServerVersion": {
|
"ServerVersion": {
|
||||||
|
|
@ -7733,40 +7837,6 @@
|
||||||
"description": "parameterBodies",
|
"description": "parameterBodies",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/EditAttachmentOptions"
|
"$ref": "#/definitions/EditAttachmentOptions"
|
||||||
},
|
|
||||||
"headers": {
|
|
||||||
"AddCollaboratorOption": {},
|
|
||||||
"AddTimeOption": {},
|
|
||||||
"CreateEmailOption": {},
|
|
||||||
"CreateForkOption": {},
|
|
||||||
"CreateHookOption": {},
|
|
||||||
"CreateIssueCommentOption": {},
|
|
||||||
"CreateIssueOption": {},
|
|
||||||
"CreateKeyOption": {},
|
|
||||||
"CreateLabelOption": {},
|
|
||||||
"CreateMilestoneOption": {},
|
|
||||||
"CreateOrgOption": {},
|
|
||||||
"CreatePullRequestOption": {},
|
|
||||||
"CreateReleaseOption": {},
|
|
||||||
"CreateRepoOption": {},
|
|
||||||
"CreateStatusOption": {},
|
|
||||||
"CreateTeamOption": {},
|
|
||||||
"CreateUserOption": {},
|
|
||||||
"DeleteEmailOption": {},
|
|
||||||
"EditAttachmentOptions": {},
|
|
||||||
"EditHookOption": {},
|
|
||||||
"EditIssueCommentOption": {},
|
|
||||||
"EditIssueOption": {},
|
|
||||||
"EditLabelOption": {},
|
|
||||||
"EditMilestoneOption": {},
|
|
||||||
"EditOrgOption": {},
|
|
||||||
"EditPullRequestOption": {},
|
|
||||||
"EditReleaseOption": {},
|
|
||||||
"EditTeamOption": {},
|
|
||||||
"EditUserOption": {},
|
|
||||||
"IssueLabelsOption": {},
|
|
||||||
"MarkdownOption": {},
|
|
||||||
"MigrateRepoForm": {}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"redirect": {
|
"redirect": {
|
||||||
|
|
@ -7806,24 +7876,16 @@
|
||||||
},
|
},
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"BasicAuth": [
|
"BasicAuth": []
|
||||||
"[]"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Token": [
|
"Token": []
|
||||||
"[]"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AccessToken": [
|
"AccessToken": []
|
||||||
"[]"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AuthorizationHeaderToken": [
|
"AuthorizationHeaderToken": []
|
||||||
"[]"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -20,10 +20,10 @@
|
||||||
// - text/html
|
// - text/html
|
||||||
//
|
//
|
||||||
// Security:
|
// Security:
|
||||||
// - BasicAuth: []
|
// - BasicAuth :
|
||||||
// - Token: []
|
// - Token :
|
||||||
// - AccessToken: []
|
// - AccessToken :
|
||||||
// - AuthorizationHeaderToken: []
|
// - AuthorizationHeaderToken :
|
||||||
//
|
//
|
||||||
// SecurityDefinitions:
|
// SecurityDefinitions:
|
||||||
// BasicAuth:
|
// BasicAuth:
|
||||||
|
|
|
||||||
|
|
@ -62,9 +62,12 @@ func MarkdownRaw(ctx *context.APIContext) {
|
||||||
// ---
|
// ---
|
||||||
// summary: Render raw markdown as HTML
|
// summary: Render raw markdown as HTML
|
||||||
// parameters:
|
// parameters:
|
||||||
// - name: body
|
// - name: body
|
||||||
// in: body
|
// in: body
|
||||||
// type: string
|
// description: Request body to render
|
||||||
|
// required: true
|
||||||
|
// schema:
|
||||||
|
// type: string
|
||||||
// consumes:
|
// consumes:
|
||||||
// - text/plain
|
// - text/plain
|
||||||
// produces:
|
// produces:
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,12 @@ func ListHooks(ctx *context.APIContext) {
|
||||||
// summary: List an organization's webhooks
|
// summary: List an organization's webhooks
|
||||||
// produces:
|
// produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: org
|
||||||
|
// in: path
|
||||||
|
// description: name of the organization
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
// responses:
|
// responses:
|
||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/HookList"
|
// "$ref": "#/responses/HookList"
|
||||||
|
|
@ -43,6 +49,17 @@ func GetHook(ctx *context.APIContext) {
|
||||||
// summary: Get a hook
|
// summary: Get a hook
|
||||||
// produces:
|
// produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: org
|
||||||
|
// in: path
|
||||||
|
// description: name of the organization
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: id
|
||||||
|
// in: path
|
||||||
|
// description: id of the hook to get
|
||||||
|
// type: integer
|
||||||
|
// required: true
|
||||||
// responses:
|
// responses:
|
||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/Hook"
|
// "$ref": "#/responses/Hook"
|
||||||
|
|
@ -64,9 +81,17 @@ func CreateHook(ctx *context.APIContext, form api.CreateHookOption) {
|
||||||
// - application/json
|
// - application/json
|
||||||
// produces:
|
// produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: org
|
||||||
|
// in: path
|
||||||
|
// description: name of the organization
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
// responses:
|
// responses:
|
||||||
// "201":
|
// "201":
|
||||||
// "$ref": "#/responses/Hook"
|
// "$ref": "#/responses/Hook"
|
||||||
|
|
||||||
|
//TODO in body params
|
||||||
if !utils.CheckCreateHookOption(ctx, &form) {
|
if !utils.CheckCreateHookOption(ctx, &form) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -82,9 +107,22 @@ func EditHook(ctx *context.APIContext, form api.EditHookOption) {
|
||||||
// - application/json
|
// - application/json
|
||||||
// produces:
|
// produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: org
|
||||||
|
// in: path
|
||||||
|
// description: name of the organization
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: id
|
||||||
|
// in: path
|
||||||
|
// description: id of the hook to update
|
||||||
|
// type: integer
|
||||||
|
// required: true
|
||||||
// responses:
|
// responses:
|
||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/Hook"
|
// "$ref": "#/responses/Hook"
|
||||||
|
|
||||||
|
//TODO in body params
|
||||||
hookID := ctx.ParamsInt64(":id")
|
hookID := ctx.ParamsInt64(":id")
|
||||||
utils.EditOrgHook(ctx, &form, hookID)
|
utils.EditOrgHook(ctx, &form, hookID)
|
||||||
}
|
}
|
||||||
|
|
@ -96,6 +134,17 @@ func DeleteHook(ctx *context.APIContext) {
|
||||||
// summary: Delete a hook
|
// summary: Delete a hook
|
||||||
// produces:
|
// produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: org
|
||||||
|
// in: path
|
||||||
|
// description: name of the organization
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: id
|
||||||
|
// in: path
|
||||||
|
// description: id of the hook to delete
|
||||||
|
// type: integer
|
||||||
|
// required: true
|
||||||
// responses:
|
// responses:
|
||||||
// "204":
|
// "204":
|
||||||
// "$ref": "#/responses/empty"
|
// "$ref": "#/responses/empty"
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ func AddTeamMember(ctx *context.APIContext) {
|
||||||
|
|
||||||
// RemoveTeamMember api for remove one member from a team
|
// RemoveTeamMember api for remove one member from a team
|
||||||
func RemoveTeamMember(ctx *context.APIContext) {
|
func RemoveTeamMember(ctx *context.APIContext) {
|
||||||
// swagger:operation DELETE /teams/{id}/members/{username} organization orgAddTeamMember
|
// swagger:operation DELETE /teams/{id}/members/{username} organization orgRemoveTeamMember
|
||||||
// ---
|
// ---
|
||||||
// summary: Remove a team member
|
// summary: Remove a team member
|
||||||
// produces:
|
// produces:
|
||||||
|
|
@ -306,7 +306,7 @@ func getRepositoryByParams(ctx *context.APIContext) *models.Repository {
|
||||||
|
|
||||||
// AddTeamRepository api for adding a repository to a team
|
// AddTeamRepository api for adding a repository to a team
|
||||||
func AddTeamRepository(ctx *context.APIContext) {
|
func AddTeamRepository(ctx *context.APIContext) {
|
||||||
// swagger:operation PUT /teams/{id}/repos/{org}/{repo} organization orgAddTeamMember
|
// swagger:operation PUT /teams/{id}/repos/{org}/{repo} organization orgAddTeamRepository
|
||||||
// ---
|
// ---
|
||||||
// summary: Add a repository to a team
|
// summary: Add a repository to a team
|
||||||
// produces:
|
// produces:
|
||||||
|
|
@ -350,7 +350,7 @@ func AddTeamRepository(ctx *context.APIContext) {
|
||||||
|
|
||||||
// RemoveTeamRepository api for removing a repository from a team
|
// RemoveTeamRepository api for removing a repository from a team
|
||||||
func RemoveTeamRepository(ctx *context.APIContext) {
|
func RemoveTeamRepository(ctx *context.APIContext) {
|
||||||
// swagger:operation DELETE /teams/{id}/repos/{org}/{repo} organization orgAddTeamMember
|
// swagger:operation DELETE /teams/{id}/repos/{org}/{repo} organization orgRemoveTeamRepository
|
||||||
// ---
|
// ---
|
||||||
// summary: Remove a repository from a team
|
// summary: Remove a repository from a team
|
||||||
// description: This does not delete the repository, it only removes the
|
// description: This does not delete the repository, it only removes the
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ func GetRawFile(ctx *context.APIContext) {
|
||||||
|
|
||||||
// GetArchive get archive of a repository
|
// GetArchive get archive of a repository
|
||||||
func GetArchive(ctx *context.APIContext) {
|
func GetArchive(ctx *context.APIContext) {
|
||||||
// swagger:operation GET /repos/{owner}/{repo}/archive/{filepath} repository repoGetArchive
|
// swagger:operation GET /repos/{owner}/{repo}/archive/{archive} repository repoGetArchive
|
||||||
// ---
|
// ---
|
||||||
// summary: Get an archive of a repository
|
// summary: Get an archive of a repository
|
||||||
// produces:
|
// produces:
|
||||||
|
|
|
||||||
|
|
@ -189,6 +189,11 @@ func EditHook(ctx *context.APIContext, form api.EditHookOption) {
|
||||||
// description: name of the repo
|
// description: name of the repo
|
||||||
// type: string
|
// type: string
|
||||||
// required: true
|
// required: true
|
||||||
|
// - name: id
|
||||||
|
// in: path
|
||||||
|
// description: index of the hook
|
||||||
|
// type: integer
|
||||||
|
// required: true
|
||||||
// - name: body
|
// - name: body
|
||||||
// in: body
|
// in: body
|
||||||
// schema:
|
// schema:
|
||||||
|
|
@ -202,7 +207,7 @@ func EditHook(ctx *context.APIContext, form api.EditHookOption) {
|
||||||
|
|
||||||
// DeleteHook delete a hook of a repository
|
// DeleteHook delete a hook of a repository
|
||||||
func DeleteHook(ctx *context.APIContext) {
|
func DeleteHook(ctx *context.APIContext) {
|
||||||
// swagger:operation DELETE /repos/{user}/{repo}/hooks/{id} repository repoDeleteHook
|
// swagger:operation DELETE /repos/{owner}/{repo}/hooks/{id} repository repoDeleteHook
|
||||||
// ---
|
// ---
|
||||||
// summary: Delete a hook in a repository
|
// summary: Delete a hook in a repository
|
||||||
// produces:
|
// produces:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2016 The Gogs Authors. All rights reserved.
|
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
@ -165,7 +166,7 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) {
|
||||||
// "$ref": "#/responses/Issue"
|
// "$ref": "#/responses/Issue"
|
||||||
|
|
||||||
var deadlineUnix util.TimeStamp
|
var deadlineUnix util.TimeStamp
|
||||||
if form.Deadline != nil {
|
if form.Deadline != nil && ctx.Repo.IsWriter() {
|
||||||
deadlineUnix = util.TimeStamp(form.Deadline.Unix())
|
deadlineUnix = util.TimeStamp(form.Deadline.Unix())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,15 +179,22 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) {
|
||||||
DeadlineUnix: deadlineUnix,
|
DeadlineUnix: deadlineUnix,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all assignee IDs
|
var assigneeIDs = make([]int64, 0)
|
||||||
assigneeIDs, err := models.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees)
|
var err error
|
||||||
if err != nil {
|
if ctx.Repo.IsWriter() {
|
||||||
if models.IsErrUserNotExist(err) {
|
issue.MilestoneID = form.Milestone
|
||||||
ctx.Error(422, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err))
|
assigneeIDs, err = models.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees)
|
||||||
} else {
|
if err != nil {
|
||||||
ctx.Error(500, "AddAssigneeByName", err)
|
if models.IsErrUserNotExist(err) {
|
||||||
|
ctx.Error(422, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err))
|
||||||
|
} else {
|
||||||
|
ctx.Error(500, "AddAssigneeByName", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return
|
} else {
|
||||||
|
// setting labels is not allowed if user is not a writer
|
||||||
|
form.Labels = make([]int64, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := models.NewIssue(ctx.Repo.Repository, issue, form.Labels, assigneeIDs, nil); err != nil {
|
if err := models.NewIssue(ctx.Repo.Repository, issue, form.Labels, assigneeIDs, nil); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ func ListIssueComments(ctx *context.APIContext) {
|
||||||
// description: name of the repo
|
// description: name of the repo
|
||||||
// type: string
|
// type: string
|
||||||
// required: true
|
// required: true
|
||||||
// - name: id
|
// - name: index
|
||||||
// in: path
|
// in: path
|
||||||
// description: index of the issue
|
// description: index of the issue
|
||||||
// type: integer
|
// type: integer
|
||||||
|
|
@ -139,7 +139,7 @@ func CreateIssueComment(ctx *context.APIContext, form api.CreateIssueCommentOpti
|
||||||
// description: name of the repo
|
// description: name of the repo
|
||||||
// type: string
|
// type: string
|
||||||
// required: true
|
// required: true
|
||||||
// - name: id
|
// - name: index
|
||||||
// in: path
|
// in: path
|
||||||
// description: index of the issue
|
// description: index of the issue
|
||||||
// type: integer
|
// type: integer
|
||||||
|
|
@ -147,7 +147,7 @@ func CreateIssueComment(ctx *context.APIContext, form api.CreateIssueCommentOpti
|
||||||
// - name: body
|
// - name: body
|
||||||
// in: body
|
// in: body
|
||||||
// schema:
|
// schema:
|
||||||
// "$ref": "#/definitions/CreateIssueOption"
|
// "$ref": "#/definitions/CreateIssueCommentOption"
|
||||||
// responses:
|
// responses:
|
||||||
// "201":
|
// "201":
|
||||||
// "$ref": "#/responses/Comment"
|
// "$ref": "#/responses/Comment"
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ func trackedTimesToAPIFormat(trackedTimes []*models.TrackedTime) []*api.TrackedT
|
||||||
|
|
||||||
// ListTrackedTimes list all the tracked times of an issue
|
// ListTrackedTimes list all the tracked times of an issue
|
||||||
func ListTrackedTimes(ctx *context.APIContext) {
|
func ListTrackedTimes(ctx *context.APIContext) {
|
||||||
// swagger:operation GET /repos/{owner}/{repo}/issues/{index}/times issue issueTrackedTimes
|
// swagger:operation GET /repos/{owner}/{repo}/issues/{id}/times issue issueTrackedTimes
|
||||||
// ---
|
// ---
|
||||||
// summary: List an issue's tracked times
|
// summary: List an issue's tracked times
|
||||||
// produces:
|
// produces:
|
||||||
|
|
@ -37,7 +37,7 @@ func ListTrackedTimes(ctx *context.APIContext) {
|
||||||
// description: name of the repo
|
// description: name of the repo
|
||||||
// type: string
|
// type: string
|
||||||
// required: true
|
// required: true
|
||||||
// - name: repo
|
// - name: id
|
||||||
// in: path
|
// in: path
|
||||||
// description: index of the issue
|
// description: index of the issue
|
||||||
// type: integer
|
// type: integer
|
||||||
|
|
@ -70,7 +70,7 @@ func ListTrackedTimes(ctx *context.APIContext) {
|
||||||
|
|
||||||
// AddTime adds time manual to the given issue
|
// AddTime adds time manual to the given issue
|
||||||
func AddTime(ctx *context.APIContext, form api.AddTimeOption) {
|
func AddTime(ctx *context.APIContext, form api.AddTimeOption) {
|
||||||
// swagger:operation Post /repos/{owner}/{repo}/issues/{index}/times issue issueAddTime
|
// swagger:operation Post /repos/{owner}/{repo}/issues/{id}/times issue issueAddTime
|
||||||
// ---
|
// ---
|
||||||
// summary: Add a tracked time to a issue
|
// summary: Add a tracked time to a issue
|
||||||
// consumes:
|
// consumes:
|
||||||
|
|
@ -132,7 +132,7 @@ func AddTime(ctx *context.APIContext, form api.AddTimeOption) {
|
||||||
|
|
||||||
// ListTrackedTimesByUser lists all tracked times of the user
|
// ListTrackedTimesByUser lists all tracked times of the user
|
||||||
func ListTrackedTimesByUser(ctx *context.APIContext) {
|
func ListTrackedTimesByUser(ctx *context.APIContext) {
|
||||||
// swagger:operation GET /repos/{owner}/{repo}/times/{tracker} user userTrackedTimes
|
// swagger:operation GET /repos/{owner}/{repo}/times/{user} user userTrackedTimes
|
||||||
// ---
|
// ---
|
||||||
// summary: List a user's tracked times in a repo
|
// summary: List a user's tracked times in a repo
|
||||||
// produces:
|
// produces:
|
||||||
|
|
|
||||||
|
|
@ -16,30 +16,7 @@ import (
|
||||||
|
|
||||||
// ListMilestones list all the milestones for a repository
|
// ListMilestones list all the milestones for a repository
|
||||||
func ListMilestones(ctx *context.APIContext) {
|
func ListMilestones(ctx *context.APIContext) {
|
||||||
// swagger:operation GET /repos/{owner}/{repo}/milestones/{id} issue issueGetMilestone
|
// swagger:operation GET /repos/{owner}/{repo}/milestones issue issueGetMilestonesList
|
||||||
// ---
|
|
||||||
// summary: Get a milestone
|
|
||||||
// produces:
|
|
||||||
// - application/json
|
|
||||||
// responses:
|
|
||||||
// "200":
|
|
||||||
// "$ref": "#/responses/Milestone"
|
|
||||||
milestones, err := models.GetMilestonesByRepoID(ctx.Repo.Repository.ID)
|
|
||||||
if err != nil {
|
|
||||||
ctx.Error(500, "GetMilestonesByRepoID", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
apiMilestones := make([]*api.Milestone, len(milestones))
|
|
||||||
for i := range milestones {
|
|
||||||
apiMilestones[i] = milestones[i].APIFormat()
|
|
||||||
}
|
|
||||||
ctx.JSON(200, &apiMilestones)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMilestone get a milestone for a repository
|
|
||||||
func GetMilestone(ctx *context.APIContext) {
|
|
||||||
// swagger:operation GET /repos/{owner}/{repo}/milestones issue issueGetMilestones
|
|
||||||
// ---
|
// ---
|
||||||
// summary: Get all of a repository's milestones
|
// summary: Get all of a repository's milestones
|
||||||
// produces:
|
// produces:
|
||||||
|
|
@ -55,6 +32,29 @@ func GetMilestone(ctx *context.APIContext) {
|
||||||
// description: name of the repo
|
// description: name of the repo
|
||||||
// type: string
|
// type: string
|
||||||
// required: true
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/MilestoneList"
|
||||||
|
milestones, err := models.GetMilestonesByRepoID(ctx.Repo.Repository.ID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(500, "GetMilestonesByRepoID", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
apiMilestones := make([]*api.Milestone, len(milestones))
|
||||||
|
for i := range milestones {
|
||||||
|
apiMilestones[i] = milestones[i].APIFormat()
|
||||||
|
}
|
||||||
|
ctx.JSON(200, &apiMilestones)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMilestone get a milestone for a repository
|
||||||
|
func GetMilestone(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /repos/{owner}/{repo}/milestones/{id} issue issueGetMilestone
|
||||||
|
// ---
|
||||||
|
// summary: Get a milestone
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
// parameters:
|
// parameters:
|
||||||
// - name: owner
|
// - name: owner
|
||||||
// in: path
|
// in: path
|
||||||
|
|
@ -68,12 +68,12 @@ func GetMilestone(ctx *context.APIContext) {
|
||||||
// required: true
|
// required: true
|
||||||
// - name: id
|
// - name: id
|
||||||
// in: path
|
// in: path
|
||||||
// description: id of the milestone to get
|
// description: id of the milestone
|
||||||
// type: integer
|
// type: integer
|
||||||
// required: true
|
// required: true
|
||||||
// responses:
|
// responses:
|
||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/MilestoneList"
|
// "$ref": "#/responses/Milestone"
|
||||||
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
|
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrMilestoneNotExist(err) {
|
if models.IsErrMilestoneNotExist(err) {
|
||||||
|
|
@ -152,6 +152,11 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) {
|
||||||
// description: name of the repo
|
// description: name of the repo
|
||||||
// type: string
|
// type: string
|
||||||
// required: true
|
// required: true
|
||||||
|
// - name: id
|
||||||
|
// in: path
|
||||||
|
// description: id of the milestone
|
||||||
|
// type: integer
|
||||||
|
// required: true
|
||||||
// - name: body
|
// - name: body
|
||||||
// in: body
|
// in: body
|
||||||
// schema:
|
// schema:
|
||||||
|
|
@ -202,7 +207,7 @@ func DeleteMilestone(ctx *context.APIContext) {
|
||||||
// description: name of the repo
|
// description: name of the repo
|
||||||
// type: string
|
// type: string
|
||||||
// required: true
|
// required: true
|
||||||
// - name: body
|
// - name: id
|
||||||
// in: path
|
// in: path
|
||||||
// description: id of the milestone to delete
|
// description: id of the milestone to delete
|
||||||
// type: integer
|
// type: integer
|
||||||
|
|
|
||||||
|
|
@ -555,13 +555,13 @@ func TopicSearch(ctx *context.Context) {
|
||||||
// ---
|
// ---
|
||||||
// summary: search topics via keyword
|
// summary: search topics via keyword
|
||||||
// produces:
|
// produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
// parameters:
|
// parameters:
|
||||||
// - name: keyword
|
// - name: q
|
||||||
// in: path
|
// in: query
|
||||||
// description: id of the repo to get
|
// description: keywords to search
|
||||||
// type: integer
|
// required: true
|
||||||
// required: true
|
// type: string
|
||||||
// responses:
|
// responses:
|
||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/Repository"
|
// "$ref": "#/responses/Repository"
|
||||||
|
|
|
||||||
|
|
@ -15,55 +15,87 @@ import (
|
||||||
// parameterBodies
|
// parameterBodies
|
||||||
// swagger:response parameterBodies
|
// swagger:response parameterBodies
|
||||||
type swaggerParameterBodies struct {
|
type swaggerParameterBodies struct {
|
||||||
|
// in:body
|
||||||
AddCollaboratorOption api.AddCollaboratorOption
|
AddCollaboratorOption api.AddCollaboratorOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
CreateEmailOption api.CreateEmailOption
|
CreateEmailOption api.CreateEmailOption
|
||||||
|
// in:body
|
||||||
DeleteEmailOption api.DeleteEmailOption
|
DeleteEmailOption api.DeleteEmailOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
CreateHookOption api.CreateHookOption
|
CreateHookOption api.CreateHookOption
|
||||||
EditHookOption api.EditHookOption
|
// in:body
|
||||||
|
EditHookOption api.EditHookOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
CreateIssueOption api.CreateIssueOption
|
CreateIssueOption api.CreateIssueOption
|
||||||
EditIssueOption api.EditIssueOption
|
// in:body
|
||||||
|
EditIssueOption api.EditIssueOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
CreateIssueCommentOption api.CreateIssueCommentOption
|
CreateIssueCommentOption api.CreateIssueCommentOption
|
||||||
EditIssueCommentOption api.EditIssueCommentOption
|
// in:body
|
||||||
|
EditIssueCommentOption api.EditIssueCommentOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
IssueLabelsOption api.IssueLabelsOption
|
IssueLabelsOption api.IssueLabelsOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
CreateKeyOption api.CreateKeyOption
|
CreateKeyOption api.CreateKeyOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
CreateLabelOption api.CreateLabelOption
|
CreateLabelOption api.CreateLabelOption
|
||||||
EditLabelOption api.EditLabelOption
|
// in:body
|
||||||
|
EditLabelOption api.EditLabelOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
MarkdownOption api.MarkdownOption
|
MarkdownOption api.MarkdownOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
CreateMilestoneOption api.CreateMilestoneOption
|
CreateMilestoneOption api.CreateMilestoneOption
|
||||||
EditMilestoneOption api.EditMilestoneOption
|
// in:body
|
||||||
|
EditMilestoneOption api.EditMilestoneOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
CreateOrgOption api.CreateOrgOption
|
CreateOrgOption api.CreateOrgOption
|
||||||
EditOrgOption api.EditOrgOption
|
// in:body
|
||||||
|
EditOrgOption api.EditOrgOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
CreatePullRequestOption api.CreatePullRequestOption
|
CreatePullRequestOption api.CreatePullRequestOption
|
||||||
EditPullRequestOption api.EditPullRequestOption
|
// in:body
|
||||||
|
EditPullRequestOption api.EditPullRequestOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
CreateReleaseOption api.CreateReleaseOption
|
CreateReleaseOption api.CreateReleaseOption
|
||||||
EditReleaseOption api.EditReleaseOption
|
// in:body
|
||||||
|
EditReleaseOption api.EditReleaseOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
CreateRepoOption api.CreateRepoOption
|
CreateRepoOption api.CreateRepoOption
|
||||||
|
// in:body
|
||||||
CreateForkOption api.CreateForkOption
|
CreateForkOption api.CreateForkOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
CreateStatusOption api.CreateStatusOption
|
CreateStatusOption api.CreateStatusOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
CreateTeamOption api.CreateTeamOption
|
CreateTeamOption api.CreateTeamOption
|
||||||
EditTeamOption api.EditTeamOption
|
// in:body
|
||||||
|
EditTeamOption api.EditTeamOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
AddTimeOption api.AddTimeOption
|
AddTimeOption api.AddTimeOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
CreateUserOption api.CreateUserOption
|
CreateUserOption api.CreateUserOption
|
||||||
EditUserOption api.EditUserOption
|
// in:body
|
||||||
|
EditUserOption api.EditUserOption
|
||||||
|
|
||||||
|
// in:body
|
||||||
MigrateRepoForm auth.MigrateRepoForm
|
MigrateRepoForm auth.MigrateRepoForm
|
||||||
|
|
||||||
|
// in:body
|
||||||
EditAttachmentOptions api.EditAttachmentOptions
|
EditAttachmentOptions api.EditAttachmentOptions
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,7 @@ type swaggerResponseWatchInfo struct {
|
||||||
// SearchResults
|
// SearchResults
|
||||||
// swagger:response SearchResults
|
// swagger:response SearchResults
|
||||||
type swaggerResponseSearchResults struct {
|
type swaggerResponseSearchResults struct {
|
||||||
|
// in:body
|
||||||
Body api.SearchResults `json:"body"`
|
Body api.SearchResults `json:"body"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,12 @@ func ListAccessTokens(ctx *context.APIContext) {
|
||||||
// summary: List the authenticated user's access tokens
|
// summary: List the authenticated user's access tokens
|
||||||
// produces:
|
// produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: username
|
||||||
|
// in: path
|
||||||
|
// description: username of user
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
// responses:
|
// responses:
|
||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/AccessTokenList"
|
// "$ref": "#/responses/AccessTokenList"
|
||||||
|
|
@ -46,6 +52,12 @@ func CreateAccessToken(ctx *context.APIContext, form api.CreateAccessTokenOption
|
||||||
// - application/json
|
// - application/json
|
||||||
// produces:
|
// produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: username
|
||||||
|
// in: path
|
||||||
|
// description: username of user
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
// responses:
|
// responses:
|
||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/AccessToken"
|
// "$ref": "#/responses/AccessToken"
|
||||||
|
|
|
||||||
|
|
@ -119,11 +119,11 @@ func checkUserFollowing(ctx *context.APIContext, u *models.User, followID int64)
|
||||||
|
|
||||||
// CheckMyFollowing whether the given user is followed by the authenticated user
|
// CheckMyFollowing whether the given user is followed by the authenticated user
|
||||||
func CheckMyFollowing(ctx *context.APIContext) {
|
func CheckMyFollowing(ctx *context.APIContext) {
|
||||||
// swagger:operation GET /user/following/{followee} user userCurrentCheckFollowing
|
// swagger:operation GET /user/following/{username} user userCurrentCheckFollowing
|
||||||
// ---
|
// ---
|
||||||
// summary: Check whether a user is followed by the authenticated user
|
// summary: Check whether a user is followed by the authenticated user
|
||||||
// parameters:
|
// parameters:
|
||||||
// - name: followee
|
// - name: username
|
||||||
// in: path
|
// in: path
|
||||||
// description: username of followed user
|
// description: username of followed user
|
||||||
// type: string
|
// type: string
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,10 @@ func Home(ctx *context.Context) {
|
||||||
user.Dashboard(ctx)
|
user.Dashboard(ctx)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
// Check non-logged users landing page.
|
||||||
|
} else if setting.LandingPageURL != setting.LandingPageHome {
|
||||||
|
ctx.Redirect(setting.AppSubURL + string(setting.LandingPageURL))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check auto-login.
|
// Check auto-login.
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,14 @@ func NewTeamPost(ctx *context.Context, form auth.CreateTeamForm) {
|
||||||
Authorize: models.ParseAccessMode(form.Permission),
|
Authorize: models.ParseAccessMode(form.Permission),
|
||||||
}
|
}
|
||||||
if t.Authorize < models.AccessModeAdmin {
|
if t.Authorize < models.AccessModeAdmin {
|
||||||
t.UnitTypes = form.Units
|
var units = make([]*models.TeamUnit, 0, len(form.Units))
|
||||||
|
for _, tp := range form.Units {
|
||||||
|
units = append(units, &models.TeamUnit{
|
||||||
|
OrgID: ctx.Org.Organization.ID,
|
||||||
|
Type: tp,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
t.Units = units
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["Team"] = t
|
ctx.Data["Team"] = t
|
||||||
|
|
@ -264,9 +271,17 @@ func EditTeamPost(ctx *context.Context, form auth.CreateTeamForm) {
|
||||||
}
|
}
|
||||||
t.Description = form.Description
|
t.Description = form.Description
|
||||||
if t.Authorize < models.AccessModeAdmin {
|
if t.Authorize < models.AccessModeAdmin {
|
||||||
t.UnitTypes = form.Units
|
var units = make([]models.TeamUnit, 0, len(form.Units))
|
||||||
|
for _, tp := range form.Units {
|
||||||
|
units = append(units, models.TeamUnit{
|
||||||
|
OrgID: t.OrgID,
|
||||||
|
TeamID: t.ID,
|
||||||
|
Type: tp,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
models.UpdateTeamUnits(t, units)
|
||||||
} else {
|
} else {
|
||||||
t.UnitTypes = nil
|
models.UpdateTeamUnits(t, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ import (
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TopicPost response for creating repository
|
// TopicsPost response for creating repository
|
||||||
func TopicPost(ctx *context.Context) {
|
func TopicsPost(ctx *context.Context) {
|
||||||
if ctx.User == nil {
|
if ctx.User == nil {
|
||||||
ctx.JSON(403, map[string]interface{}{
|
ctx.JSON(403, map[string]interface{}{
|
||||||
"message": "Only owners could change the topics.",
|
"message": "Only owners could change the topics.",
|
||||||
|
|
@ -27,6 +27,37 @@ func TopicPost(ctx *context.Context) {
|
||||||
topics = strings.Split(topicsStr, ",")
|
topics = strings.Split(topicsStr, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invalidTopics := make([]string, 0)
|
||||||
|
i := 0
|
||||||
|
for _, topic := range topics {
|
||||||
|
topic = strings.TrimSpace(strings.ToLower(topic))
|
||||||
|
// ignore empty string
|
||||||
|
if len(topic) > 0 {
|
||||||
|
topics[i] = topic
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if !models.ValidateTopic(topic) {
|
||||||
|
invalidTopics = append(invalidTopics, topic)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
topics = topics[:i]
|
||||||
|
|
||||||
|
if len(topics) > 25 {
|
||||||
|
ctx.JSON(422, map[string]interface{}{
|
||||||
|
"invalidTopics": topics[:0],
|
||||||
|
"message": ctx.Tr("repo.topic.count_prompt"),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(invalidTopics) > 0 {
|
||||||
|
ctx.JSON(422, map[string]interface{}{
|
||||||
|
"invalidTopics": invalidTopics,
|
||||||
|
"message": ctx.Tr("repo.topic.format_prompt"),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
err := models.SaveTopics(ctx.Repo.Repository.ID, topics...)
|
err := models.SaveTopics(ctx.Repo.Repository.ID, topics...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(2, "SaveTopics failed: %v", err)
|
log.Error(2, "SaveTopics failed: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,7 @@ func GogsHooksNewPost(ctx *context.Context, form auth.NewGogshookForm) {
|
||||||
Secret: form.Secret,
|
Secret: form.Secret,
|
||||||
HookEvent: ParseHookEvent(form.WebhookForm),
|
HookEvent: ParseHookEvent(form.WebhookForm),
|
||||||
IsActive: form.Active,
|
IsActive: form.Active,
|
||||||
HookTaskType: models.GITEA,
|
HookTaskType: models.GOGS,
|
||||||
OrgID: orCtx.OrgID,
|
OrgID: orCtx.OrgID,
|
||||||
}
|
}
|
||||||
if err := w.UpdateEvent(); err != nil {
|
if err := w.UpdateEvent(); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -486,7 +486,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||||
m.Get("/:id", repo.WebHooksEdit)
|
m.Get("/:id", repo.WebHooksEdit)
|
||||||
m.Post("/:id/test", repo.TestWebhook)
|
m.Post("/:id/test", repo.TestWebhook)
|
||||||
m.Post("/gitea/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost)
|
m.Post("/gitea/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost)
|
||||||
m.Post("/gogs/:id", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost)
|
m.Post("/gogs/:id", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksEditPost)
|
||||||
m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost)
|
m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost)
|
||||||
m.Post("/discord/:id", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost)
|
m.Post("/discord/:id", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost)
|
||||||
m.Post("/dingtalk/:id", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost)
|
m.Post("/dingtalk/:id", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost)
|
||||||
|
|
@ -626,7 +626,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||||
}, context.RepoAssignment(), context.UnitTypes(), context.LoadRepoUnits(), context.CheckUnit(models.UnitTypeReleases))
|
}, context.RepoAssignment(), context.UnitTypes(), context.LoadRepoUnits(), context.CheckUnit(models.UnitTypeReleases))
|
||||||
|
|
||||||
m.Group("/:username/:reponame", func() {
|
m.Group("/:username/:reponame", func() {
|
||||||
m.Post("/topics", repo.TopicPost)
|
m.Post("/topics", repo.TopicsPost)
|
||||||
}, context.RepoAssignment(), reqRepoAdmin)
|
}, context.RepoAssignment(), reqRepoAdmin)
|
||||||
|
|
||||||
m.Group("/:username/:reponame", func() {
|
m.Group("/:username/:reponame", func() {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/go-macaron/captcha"
|
"github.com/go-macaron/captcha"
|
||||||
"github.com/markbates/goth"
|
"github.com/markbates/goth"
|
||||||
|
|
@ -474,7 +475,7 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR
|
||||||
return setting.AppSubURL + "/"
|
return setting.AppSubURL + "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
|
if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 && !util.IsExternalURL(redirectTo) {
|
||||||
ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)
|
ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)
|
||||||
if obeyRedirect {
|
if obeyRedirect {
|
||||||
ctx.RedirectToFirst(redirectTo)
|
ctx.RedirectToFirst(redirectTo)
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,11 @@ func Issues(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
userRepoIDs, err = ctxUser.GetAccessRepoIDs()
|
unitType := models.UnitTypeIssues
|
||||||
|
if isPullList {
|
||||||
|
unitType = models.UnitTypePullRequests
|
||||||
|
}
|
||||||
|
userRepoIDs, err = ctxUser.GetAccessRepoIDs(unitType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("ctxUser.GetAccessRepoIDs", err)
|
ctx.ServerError("ctxUser.GetAccessRepoIDs", err)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ func TestIssues(t *testing.T) {
|
||||||
Issues(ctx)
|
Issues(ctx)
|
||||||
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
||||||
|
|
||||||
assert.EqualValues(t, map[int64]int64{1: 1, 2: 1}, ctx.Data["Counts"])
|
assert.EqualValues(t, map[int64]int64{1: 1}, ctx.Data["Counts"])
|
||||||
assert.EqualValues(t, true, ctx.Data["IsShowClosed"])
|
assert.EqualValues(t, true, ctx.Data["IsShowClosed"])
|
||||||
assert.Len(t, ctx.Data["Issues"], 1)
|
assert.Len(t, ctx.Data["Issues"], 1)
|
||||||
assert.Len(t, ctx.Data["Repos"], 2)
|
assert.Len(t, ctx.Data["Repos"], 1)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,7 @@ func Account(ctx *context.Context) {
|
||||||
ctx.Data["PageIsSettingsAccount"] = true
|
ctx.Data["PageIsSettingsAccount"] = true
|
||||||
ctx.Data["Email"] = ctx.User.Email
|
ctx.Data["Email"] = ctx.User.Email
|
||||||
|
|
||||||
emails, err := models.GetEmailAddresses(ctx.User.ID)
|
loadAccountData(ctx)
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetEmailAddresses", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["Emails"] = emails
|
|
||||||
|
|
||||||
ctx.HTML(200, tplSettingsAccount)
|
ctx.HTML(200, tplSettingsAccount)
|
||||||
}
|
}
|
||||||
|
|
@ -40,6 +35,8 @@ func AccountPost(ctx *context.Context, form auth.ChangePasswordForm) {
|
||||||
ctx.Data["PageIsSettingsAccount"] = true
|
ctx.Data["PageIsSettingsAccount"] = true
|
||||||
|
|
||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
|
loadAccountData(ctx)
|
||||||
|
|
||||||
ctx.HTML(200, tplSettingsAccount)
|
ctx.HTML(200, tplSettingsAccount)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -85,15 +82,9 @@ func EmailPost(ctx *context.Context, form auth.AddEmailForm) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Email address.
|
|
||||||
emails, err := models.GetEmailAddresses(ctx.User.ID)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetEmailAddresses", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["Emails"] = emails
|
|
||||||
|
|
||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
|
loadAccountData(ctx)
|
||||||
|
|
||||||
ctx.HTML(200, tplSettingsAccount)
|
ctx.HTML(200, tplSettingsAccount)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -105,6 +96,8 @@ func EmailPost(ctx *context.Context, form auth.AddEmailForm) {
|
||||||
}
|
}
|
||||||
if err := models.AddEmailAddress(email); err != nil {
|
if err := models.AddEmailAddress(email); err != nil {
|
||||||
if models.IsErrEmailAlreadyUsed(err) {
|
if models.IsErrEmailAlreadyUsed(err) {
|
||||||
|
loadAccountData(ctx)
|
||||||
|
|
||||||
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSettingsAccount, &form)
|
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSettingsAccount, &form)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -149,6 +142,8 @@ func DeleteAccount(ctx *context.Context) {
|
||||||
|
|
||||||
if _, err := models.UserSignIn(ctx.User.Name, ctx.Query("password")); err != nil {
|
if _, err := models.UserSignIn(ctx.User.Name, ctx.Query("password")); err != nil {
|
||||||
if models.IsErrUserNotExist(err) {
|
if models.IsErrUserNotExist(err) {
|
||||||
|
loadAccountData(ctx)
|
||||||
|
|
||||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), tplSettingsAccount, nil)
|
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), tplSettingsAccount, nil)
|
||||||
} else {
|
} else {
|
||||||
ctx.ServerError("UserSignIn", err)
|
ctx.ServerError("UserSignIn", err)
|
||||||
|
|
@ -172,3 +167,12 @@ func DeleteAccount(ctx *context.Context) {
|
||||||
ctx.Redirect(setting.AppSubURL + "/")
|
ctx.Redirect(setting.AppSubURL + "/")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadAccountData(ctx *context.Context) {
|
||||||
|
emails, err := models.GetEmailAddresses(ctx.User.ID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("GetEmailAddresses", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Data["Emails"] = emails
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,7 @@ func Applications(ctx *context.Context) {
|
||||||
ctx.Data["Title"] = ctx.Tr("settings")
|
ctx.Data["Title"] = ctx.Tr("settings")
|
||||||
ctx.Data["PageIsSettingsApplications"] = true
|
ctx.Data["PageIsSettingsApplications"] = true
|
||||||
|
|
||||||
tokens, err := models.ListAccessTokens(ctx.User.ID)
|
loadApplicationsData(ctx)
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("ListAccessTokens", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["Tokens"] = tokens
|
|
||||||
|
|
||||||
ctx.HTML(200, tplSettingsApplications)
|
ctx.HTML(200, tplSettingsApplications)
|
||||||
}
|
}
|
||||||
|
|
@ -38,12 +33,8 @@ func ApplicationsPost(ctx *context.Context, form auth.NewAccessTokenForm) {
|
||||||
ctx.Data["PageIsSettingsApplications"] = true
|
ctx.Data["PageIsSettingsApplications"] = true
|
||||||
|
|
||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
tokens, err := models.ListAccessTokens(ctx.User.ID)
|
loadApplicationsData(ctx)
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("ListAccessTokens", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["Tokens"] = tokens
|
|
||||||
ctx.HTML(200, tplSettingsApplications)
|
ctx.HTML(200, tplSettingsApplications)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -75,3 +66,12 @@ func DeleteApplication(ctx *context.Context) {
|
||||||
"redirect": setting.AppSubURL + "/user/settings/applications",
|
"redirect": setting.AppSubURL + "/user/settings/applications",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadApplicationsData(ctx *context.Context) {
|
||||||
|
tokens, err := models.ListAccessTokens(ctx.User.ID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("ListAccessTokens", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Data["Tokens"] = tokens
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,19 +23,7 @@ func Keys(ctx *context.Context) {
|
||||||
ctx.Data["PageIsSettingsKeys"] = true
|
ctx.Data["PageIsSettingsKeys"] = true
|
||||||
ctx.Data["DisableSSH"] = setting.SSH.Disabled
|
ctx.Data["DisableSSH"] = setting.SSH.Disabled
|
||||||
|
|
||||||
keys, err := models.ListPublicKeys(ctx.User.ID)
|
loadKeysData(ctx)
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("ListPublicKeys", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["Keys"] = keys
|
|
||||||
|
|
||||||
gpgkeys, err := models.ListGPGKeys(ctx.User.ID)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("ListGPGKeys", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["GPGKeys"] = gpgkeys
|
|
||||||
|
|
||||||
ctx.HTML(200, tplSettingsKeys)
|
ctx.HTML(200, tplSettingsKeys)
|
||||||
}
|
}
|
||||||
|
|
@ -45,21 +33,9 @@ func KeysPost(ctx *context.Context, form auth.AddKeyForm) {
|
||||||
ctx.Data["Title"] = ctx.Tr("settings")
|
ctx.Data["Title"] = ctx.Tr("settings")
|
||||||
ctx.Data["PageIsSettingsKeys"] = true
|
ctx.Data["PageIsSettingsKeys"] = true
|
||||||
|
|
||||||
keys, err := models.ListPublicKeys(ctx.User.ID)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("ListPublicKeys", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["Keys"] = keys
|
|
||||||
|
|
||||||
gpgkeys, err := models.ListGPGKeys(ctx.User.ID)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("ListGPGKeys", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["GPGKeys"] = gpgkeys
|
|
||||||
|
|
||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
|
loadKeysData(ctx)
|
||||||
|
|
||||||
ctx.HTML(200, tplSettingsKeys)
|
ctx.HTML(200, tplSettingsKeys)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -73,9 +49,13 @@ func KeysPost(ctx *context.Context, form auth.AddKeyForm) {
|
||||||
ctx.Flash.Error(ctx.Tr("form.invalid_gpg_key", err.Error()))
|
ctx.Flash.Error(ctx.Tr("form.invalid_gpg_key", err.Error()))
|
||||||
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
|
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
|
||||||
case models.IsErrGPGKeyIDAlreadyUsed(err):
|
case models.IsErrGPGKeyIDAlreadyUsed(err):
|
||||||
|
loadKeysData(ctx)
|
||||||
|
|
||||||
ctx.Data["Err_Content"] = true
|
ctx.Data["Err_Content"] = true
|
||||||
ctx.RenderWithErr(ctx.Tr("settings.gpg_key_id_used"), tplSettingsKeys, &form)
|
ctx.RenderWithErr(ctx.Tr("settings.gpg_key_id_used"), tplSettingsKeys, &form)
|
||||||
case models.IsErrGPGNoEmailFound(err):
|
case models.IsErrGPGNoEmailFound(err):
|
||||||
|
loadKeysData(ctx)
|
||||||
|
|
||||||
ctx.Data["Err_Content"] = true
|
ctx.Data["Err_Content"] = true
|
||||||
ctx.RenderWithErr(ctx.Tr("settings.gpg_no_key_email_found"), tplSettingsKeys, &form)
|
ctx.RenderWithErr(ctx.Tr("settings.gpg_no_key_email_found"), tplSettingsKeys, &form)
|
||||||
default:
|
default:
|
||||||
|
|
@ -103,9 +83,13 @@ func KeysPost(ctx *context.Context, form auth.AddKeyForm) {
|
||||||
ctx.Data["HasSSHError"] = true
|
ctx.Data["HasSSHError"] = true
|
||||||
switch {
|
switch {
|
||||||
case models.IsErrKeyAlreadyExist(err):
|
case models.IsErrKeyAlreadyExist(err):
|
||||||
|
loadKeysData(ctx)
|
||||||
|
|
||||||
ctx.Data["Err_Content"] = true
|
ctx.Data["Err_Content"] = true
|
||||||
ctx.RenderWithErr(ctx.Tr("settings.ssh_key_been_used"), tplSettingsKeys, &form)
|
ctx.RenderWithErr(ctx.Tr("settings.ssh_key_been_used"), tplSettingsKeys, &form)
|
||||||
case models.IsErrKeyNameAlreadyUsed(err):
|
case models.IsErrKeyNameAlreadyUsed(err):
|
||||||
|
loadKeysData(ctx)
|
||||||
|
|
||||||
ctx.Data["Err_Title"] = true
|
ctx.Data["Err_Title"] = true
|
||||||
ctx.RenderWithErr(ctx.Tr("settings.ssh_key_name_used"), tplSettingsKeys, &form)
|
ctx.RenderWithErr(ctx.Tr("settings.ssh_key_name_used"), tplSettingsKeys, &form)
|
||||||
default:
|
default:
|
||||||
|
|
@ -147,3 +131,19 @@ func DeleteKey(ctx *context.Context) {
|
||||||
"redirect": setting.AppSubURL + "/user/settings/keys",
|
"redirect": setting.AppSubURL + "/user/settings/keys",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadKeysData(ctx *context.Context) {
|
||||||
|
keys, err := models.ListPublicKeys(ctx.User.ID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("ListPublicKeys", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Data["Keys"] = keys
|
||||||
|
|
||||||
|
gpgkeys, err := models.ListGPGKeys(ctx.User.ID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("ListGPGKeys", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Data["GPGKeys"] = gpgkeys
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ const (
|
||||||
func Profile(ctx *context.Context) {
|
func Profile(ctx *context.Context) {
|
||||||
ctx.Data["Title"] = ctx.Tr("settings")
|
ctx.Data["Title"] = ctx.Tr("settings")
|
||||||
ctx.Data["PageIsSettingsProfile"] = true
|
ctx.Data["PageIsSettingsProfile"] = true
|
||||||
|
|
||||||
ctx.HTML(200, tplSettingsProfile)
|
ctx.HTML(200, tplSettingsProfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user