Compare commits

..

26 Commits

Author SHA1 Message Date
Lauris Bukšis-Haberkorns
b27e10d6e4 Change 1.4.0-rc1 version release date
Signed-off-by: Lauris Bukšis-Haberkorns <lauris@nix.lv>
2018-02-01 10:22:24 +02:00
GiteaBot
b62ce2e246 [skip ci] Updated translations via Crowdin 2018-01-31 15:41:59 +00:00
Morgan Bazalgette
10171b7e2f add changelog for 1.4.0 (#3435)
* add changelog for 1.4.0

* remove docs

* Remove some more noise

* Small reorganization, removed bugfixes that were not present in last stable version

* Move LFS lock to features, add just merged bugfix info
2018-01-31 17:40:57 +02:00
Lauris BH
f9a5cc4d8e Use correct transaltion key for delete email button (#3422) 2018-01-31 00:31:06 +02:00
Antoine GIRARD
b3fd94c13d Add sensitive headers (#3429)
* Add HeaderWithSensitiveCase methods to respect casing

* Update webhook.go
2018-01-31 00:09:16 +02:00
GiteaBot
d09704e903 [skip ci] Updated translations via Crowdin 2018-01-30 12:30:54 +00:00
Lauris BH
ca4f5c37e6 Fix branch deletion for squash or rebase merged pull requests (#3425) 2018-01-30 14:29:39 +02:00
GiteaBot
5911f98392 [skip ci] Updated translations via Crowdin 2018-01-29 17:50:28 +00:00
Lauris BH
aef30071c9 Fix go-get content type (#3426) 2018-01-29 19:50:04 +02:00
GiteaBot
7af81973cb [skip ci] Updated translations via Crowdin 2018-01-29 11:15:41 +00:00
Ethan Koenig
46c7fe371d Fix PR merge error (#3421) 2018-01-29 12:18:20 +02:00
Lauris BH
28b81899d0 Add doctype to go-get=1 reponse (#3423) 2018-01-29 03:12:04 +02:00
Ethan Koenig
3968c1149e Fix SQL type error for webhooks (#3424) 2018-01-29 02:26:01 +02:00
Lauris BH
e189b06baa Add mising LOCAL_WIKI_PATH documentation (#3420) 2018-01-28 19:16:28 +02:00
GiteaBot
7fd2d8e392 [skip ci] Updated translations via Crowdin 2018-01-28 12:25:26 +00:00
Ethan Koenig
bac6ac033a Fix race condition in repo renaming (#3418) 2018-01-28 14:24:59 +02:00
Ethan Koenig
c55a027da3 Fix empty checkout bug (#3419) 2018-01-28 13:27:42 +02:00
Antoine GIRARD
36a94da8da doc: Improve integrations examples (#3416) 2018-01-27 20:52:41 +02:00
Timo Schindler
bcd7f42529 Added quoting for passwords in sample.app.ini and documentation (#3395) 2018-01-27 20:35:49 +02:00
Wendell Sun
b627f1131b Change local copy origin url after repository rename (#3399)
Fix #3378
2018-01-27 19:54:26 +02:00
Antoine GIRARD
9e842c8a72 Fix SSH auth lfs locks (#3152)
* Fix SSH auth LFS locks

* Activate SSH/lock test

* Remove debug

* Follow @lunny recommendation for AfterLoad method
2018-01-27 18:48:15 +02:00
Lunny Xiao
97fe773491 fix MSSQL bug on org (#3405) 2018-01-27 17:20:59 +02:00
Lauris BH
a0c397df08 Recognize more characters in crossreferenced repo name (#3413) 2018-01-27 14:33:32 +02:00
GiteaBot
9e87fe8c06 [skip ci] Updated translations via Crowdin 2018-01-27 02:18:45 +00:00
Kazuki Sawada
07b4e47a56 Add myself to TRANSLATORS (#3415) 2018-01-26 20:17:26 -06:00
GiteaBot
82a7b0292e [skip ci] Updated translations via Crowdin 2018-01-25 14:03:22 +00:00
65 changed files with 5492 additions and 474 deletions

View File

@@ -1,5 +1,113 @@
# Changelog
This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.4.0-rc1](https://github.com/go-gitea/gitea/releases/tag/v1.4.0-rc1) - 2018-02-01
* BREAKING
* Drop deprecated GOGS\_WORK\_DIR use (#2946)
* Fix API status code for hook creation (#2814)
* SECURITY
* Sanitize logs for mirror sync (#3057)
* FEATURE
* Serve .patch and .diff for pull requests (#3305, #3293)
* Add repo-sync-releases admin command (#3254)
* Support default private when creating or migrating repository (#3239)
* Writable deploy keys (closes #671) (#3225)
* Add Pull Request merge options - Ignore white-space for conflict checking, Rebase, Squash merge (#3188)
* Added progressbar for issues with checkboxes (#1146). (#3171)
* Mention completion for issue editor. (#3136)
* Add 'mark all read' option to notifications (#3097)
* Git LFS lock api (#2938)
* Add reactions to issues/PR and comments (#2856)
* Add dingtalk webhook (#2777)
* Responsive view (#2750)
* BUGFIXES
* Fix webhook X-GitHub-* headers casing for better compatibility (#3429)
* Add content type and doctype to requests made with go-get (#3426, #3423)
* Fix SQL type error for webhooks (#3424)
* Fix PR merge error (#3421)
* Recognize more characters in crossreferenced repo name (#3413)
* Fix MSSQL bug on org (#3405)
* HTML escape all lines of the search result (#3402)
* Change local copy origin url after repository rename (#3399)
* Force-push to base repo's ref/pull/#/head (#3393)
* Fix bug when a user delete but assigned on issue (#3318)
* Use issue number/index instead of id for API URL. Fix #3297 (#3298)
* Fix repo-transfer-and-team-repo-count bug (#3241)
* Fix always-on SSL Mode checkbox in admin page (#3208)
* Fix source download link when no code unit allowed (#3166)
* Fix org owner cannot be removed if he is not in owner team (#3164)
* Fix run web with -p push failed (#3154)
* Fix gpg tmpl (#3153)
* Fix SSH auth lfs locks (#3152)
* Improvements for supporting UI Location (#3146)
* Fix new pull request link (#3133)
* Fix missing branch in release bug (#3108)
* Allow adding collaborators with (fullname) (#3103)
* Fix repo links (#3093)
* fix lfs url refs + keep path upper/lowercase in db. (#3092)
* Fix redis session failed (#3086)
* Fix bugs in issue dashboard stats (#3073)
* Fix avatar URLs (#3069)
* Fix ref parsing in commit messages (#3067)
* Fix issue list branch link broken (#3061)
* sendmail: correct option to set envelope-sender (#3044)
* Fix missing password length check when change password (#3039)
* Fix git lfs path (#3016)
* Fix API-Endpoint release (#3005) (#3012)
* Set OpenID support on by default when installing new instance (#3010)
* Various wiki bug fixes (#2996)
* Fix go-get, src and raw urls to new scheme (#2978)
* Fix error when add user has full name to team (#2973)
* Fix memcache support when value is returned as string always (#2924)
* ENHANCEMENT
* Use GiteaServer as the user agent for http requests (#3404)
* Delete indexer DB entries when (re)creating index (#3385)
* Change how merged PR commit info are prepared (#3368)
* Asynchronously populate the repo indexer (#3366)
* Make the default action for the gitea executable that of running the webserver (#3331)
* Templates for extra links in top navbar and repo tool tabs. (#3308)
* Fixed asterisk based tasklist items #3295 (#3296)
* Add more additional template snippets (#3286)
* Open external tracker in blank window, consistently with wiki (#3227)
* Fix repo links on user profile (#3197)
* Enable emoji for wiki view (#3158)
* Small improve on deleting attachements (#3145)
* Reduce overhead of upgrades for users with custom stylesheets/JS (#3051)
* Default log level to Info without hardcoding it in installer (#3041)
* Memory usage improvements (#3013)
* Add fingerprint to ssh key endpoints. (#3009)
* Improve memory usage when reaching diff limits (#2990)
* Expandable commit bodies (#2980)
* Update gitgraph.js to fix blurry commit graph on HiDPI screens (#2957)
* Fix language names (#2955)
* Remove render issue link (#2954)
* Page parameter for repo search API (#2915)
* Apply LANDING\_PAGE config options for logged in users (#2894)
* Enable admin to search by email (#2888)
* Hide add key button if SSH is disabled (#2873)
* Fix comment API paths (#2813)
* Add an option to allow redirect of http port 80 to https. (#1928)
* MISC
* Fix organization profile on mobile devices (#3332)
* Fix guide link for webhooks in repository settings (#3291) (#3292)
* Enable Libravatar by default in new installations (#3287)
* Improve suppressed diff boxes (#3193)
* fix button heights on commits page (#3091)
* Minor copy changes (#3074)
* Sort repos in issues dashboard sidebar (#3072)
* Remove box-shadow from UI, fix dashboard issue (#3065)
* Adjust branch button size (#3063)
* Fix misalignment issue in repo header (#3062)
* Delete a user's public key via admin api (closes #3014) (#3059)
* Dashboard: Fix line height problem in issue titles (#3054)
* Remove duplicate "Max Diff Lines" from config view (#2987)
* Drop unmaintained gogs migration script (#2947)
* App restarts to quickly if it fails to start. (#2945)
* Add owner to delete repo message (#2886)
## [1.3.1](https://github.com/go-gitea/gitea/releases/tag/v1.3.1) - 2017-12-08
* BUGFIXES
* Sanitize logs for mirror sync (#3057, #3082) (#3078)

View File

@@ -259,12 +259,16 @@ func runServ(c *cli.Context) error {
url := fmt.Sprintf("%s%s/%s.git/info/lfs", setting.AppURL, username, repo.Name)
now := time.Now()
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
claims := jwt.MapClaims{
"repo": repo.ID,
"op": lfsVerb,
"exp": now.Add(5 * time.Minute).Unix(),
"nbf": now.Unix(),
})
}
if user != nil {
claims["user"] = user.ID
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// Sign and get the complete encoded token as a string using the secret
tokenString, err := token.SignedString(setting.LFS.JWTSecretBytes)

View File

@@ -41,8 +41,10 @@ LINE_WRAP_EXTENSIONS = .txt,.md,.markdown,.mdown,.mkd,
PREVIEWABLE_FILE_MODES = markdown
[repository.local]
; Path for uploads. Defaults to `tmp/local-repo`
; Path for local repository copy. Defaults to `tmp/local-repo`
LOCAL_COPY_PATH = tmp/local-repo
; Path for local wiki copy. Defaults to `tmp/local-wiki`
LOCAL_WIKI_PATH = tmp/local-wiki
[repository.upload]
; Whether repository file uploads are enabled. Defaults to `true`
@@ -198,6 +200,7 @@ DB_TYPE = mysql
HOST = 127.0.0.1:3306
NAME = gitea
USER = root
; Use PASSWD = `your password` for quoting if you use special characters in the password.
PASSWD =
; For "postgres" only, either "disable", "require" or "verify-full"
SSL_MODE = disable
@@ -342,6 +345,7 @@ KEY_FILE = custom/mailer/key.pem
FROM =
; Mailer user name and password
USER =
; Use PASSWD = `your password` for quoting if you use special characters in the password.
PASSWD =
; Send mails as plain text
SEND_AS_PLAIN_TEXT = false
@@ -464,6 +468,7 @@ SUBJECT = Diagnostic message from server
HOST =
; Mailer user name and password
USER =
; Use PASSWD = `your password` for quoting if you use special characters in the password.
PASSWD =
; Receivers, can be one or more, e.g. 1@example.com,2@example.com
RECEIVERS =

View File

@@ -118,7 +118,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `HOST`: **127.0.0.1:3306**: Database host address and port.
- `NAME`: **gitea**: Database name.
- `USER`: **root**: Database username.
- `PASSWD`: **\<empty\>**: Database user password.
- `PASSWD`: **\<empty\>**: Database user password. Use \`your password\` for quoting if you use special characters in the password.
- `SSL_MODE`: **disable**: For PostgreSQL only.
- `PATH`: **data/gitea.db**: For SQLite3 only, the database file path.
@@ -185,7 +185,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `FROM`: **\<empty\>**: Mail from address, RFC 5322. This can be just an email address, or
the "Name" \<email@example.com\> format.
- `USER`: **\<empty\>**: Username of mailing user (usually the sender's e-mail address).
- `PASSWD`: **\<empty\>**: Password of mailing user.
- `PASSWD`: **\<empty\>**: Password of mailing user. Use \`your password\` for quoting if you use special characters in the password.
- `SKIP_VERIFY`: **\<empty\>**: Do not verify the self-signed certificates.
- **Note:** Gitea only supports SMTP with STARTTLS.
- `USE_SENDMAIL`: **false** Use the operating system's `sendmail` command instead of SMTP.

View File

@@ -1,3 +1,5 @@
# Integrations tests
Integration tests can be run with make commands for the
appropriate backends, namely:
@@ -5,7 +7,42 @@ appropriate backends, namely:
make test-pgsql
make test-sqlite
# Running individual tests
Make sure to perform a clean build before running tests:
make clean build
## Run all tests via local drone
```
drone exec --local --build.event "pull_request"
```
## Run sqlite integrations tests
Start tests
```
make test-sqlite
```
## Run mysql integrations tests
Setup a mysql database inside docker
```
docker run -e "MYSQL_DATABASE=test" -e "MYSQL_ALLOW_EMPTY_PASSWORD=yes" --rm --name mysql mysql:5.7 #(just ctrl-c to stop db and clean the container)
```
Start tests based on the database container
```
TEST_MYSQL_HOST="$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mysql):3306" TEST_MYSQL_DBNAME=test TEST_MYSQL_USERNAME=root TEST_MYSQL_PASSWORD='' make test-mysql
```
## Run pgsql integrations tests
Setup a pgsql database inside docker
```
docker run -e "POSTGRES_DB=test" --rm --name pgsql postgres:9.5 #(just ctrl-c to stop db and clean the container)
```
Start tests based on the database container
```
TEST_PGSQL_HOST=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' pgsql) TEST_PGSQL_DBNAME=test TEST_PGSQL_USERNAME=postgres TEST_PGSQL_PASSWORD=postgres make test-pgsql
```
## Running individual tests
Example command to run GPG test with sqlite backend:
@@ -17,6 +54,3 @@ go test -c code.gitea.io/gitea/integrations \
-test.v -test.run GPG
```
Make sure to perform a clean build before running tests:
make clean build

View File

@@ -41,10 +41,10 @@ func TestAPILFSLocksNotLogin(t *testing.T) {
req := NewRequestf(t, "GET", "/%s/%s.git/info/lfs/locks", user.Name, repo.Name)
req.Header.Set("Accept", "application/vnd.git-lfs+json")
resp := MakeRequest(t, req, http.StatusForbidden)
resp := MakeRequest(t, req, http.StatusUnauthorized)
var lfsLockError api.LFSLockError
DecodeJSON(t, resp, &lfsLockError)
assert.Equal(t, "You must have pull access to list locks : User undefined doesn't have rigth to list for lfs lock [rid: 1]", lfsLockError.Message)
assert.Equal(t, "Unauthorized", lfsLockError.Message)
}
func TestAPILFSLocksLogged(t *testing.T) {
@@ -68,8 +68,8 @@ func TestAPILFSLocksLogged(t *testing.T) {
{user: user2, repo: repo1, path: "path/test", httpResult: http.StatusConflict},
{user: user2, repo: repo1, path: "Foo/BaR.zip", httpResult: http.StatusConflict},
{user: user2, repo: repo1, path: "Foo/Test/../subFOlder/../Relative/../BaR.zip", httpResult: http.StatusConflict},
{user: user4, repo: repo1, path: "FoO/BaR.zip", httpResult: http.StatusForbidden},
{user: user4, repo: repo1, path: "path/test-user4", httpResult: http.StatusForbidden},
{user: user4, repo: repo1, path: "FoO/BaR.zip", httpResult: http.StatusUnauthorized},
{user: user4, repo: repo1, path: "path/test-user4", httpResult: http.StatusUnauthorized},
{user: user2, repo: repo1, path: "patH/Test-user4", httpResult: http.StatusCreated, addTime: []int{0}},
{user: user2, repo: repo1, path: "some/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/path", httpResult: http.StatusCreated, addTime: []int{0}},

View File

@@ -214,11 +214,9 @@ func TestGit(t *testing.T) {
commitAndPush(t, bigSize, dstPath)
})
})
/* Failed without #3152. TODO activate with fix.
t.Run("Locks", func(t *testing.T) {
lockTest(t, u.String(), dstPath)
lockTest(t, u.String(), dstPath)
})
*/
})
})
})

View File

@@ -530,21 +530,24 @@ func (err ErrLFSLockNotExist) Error() string {
return fmt.Sprintf("lfs lock does not exist [id: %d, rid: %d, path: %s]", err.ID, err.RepoID, err.Path)
}
// ErrLFSLockUnauthorizedAction represents a "LFSLockUnauthorizedAction" kind of error.
type ErrLFSLockUnauthorizedAction struct {
// ErrLFSUnauthorizedAction represents a "LFSUnauthorizedAction" kind of error.
type ErrLFSUnauthorizedAction struct {
RepoID int64
UserName string
Action string
Mode AccessMode
}
// IsErrLFSLockUnauthorizedAction checks if an error is a ErrLFSLockUnauthorizedAction.
func IsErrLFSLockUnauthorizedAction(err error) bool {
_, ok := err.(ErrLFSLockUnauthorizedAction)
// IsErrLFSUnauthorizedAction checks if an error is a ErrLFSUnauthorizedAction.
func IsErrLFSUnauthorizedAction(err error) bool {
_, ok := err.(ErrLFSUnauthorizedAction)
return ok
}
func (err ErrLFSLockUnauthorizedAction) Error() string {
return fmt.Sprintf("User %s doesn't have rigth to %s for lfs lock [rid: %d]", err.UserName, err.Action, err.RepoID)
func (err ErrLFSUnauthorizedAction) Error() string {
if err.Mode == AccessModeWrite {
return fmt.Sprintf("User %s doesn't have write access for lfs lock [rid: %d]", err.UserName, err.RepoID)
}
return fmt.Sprintf("User %s doesn't have read access for lfs lock [rid: %d]", err.UserName, err.RepoID)
}
// ErrLFSLockAlreadyExist represents a "LFSLockAlreadyExist" kind of error.

View File

@@ -247,54 +247,30 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
lineCount int
curFileLinesCount int
curFileLFSPrefix bool
input = bufio.NewReader(reader)
isEOF = false
)
input := bufio.NewReader(reader)
isEOF := false
for !isEOF {
var linebuf bytes.Buffer
for {
peek, err := input.Peek(maxLineCharacters)
if err != nil && err != bufio.ErrBufferFull {
return nil, fmt.Errorf("PeekByte: %v", err)
}
newLine := bytes.IndexByte(peek, '\n');
if newLine == -1 {
// Instead of reading things, and copying memory around,
// we simply discard them (which doesn't allocate memory)
curFile.IsIncomplete = true
// We already know that we can read `len(peek)` amount of bytes,
// hence no error-checking
input.Discard(len(peek))
continue
}
if curFile.IsIncomplete {
// Since we get here without hiting the above case, we've found a newline
// and only discard that part.
input.Discard(newLine)
break
}
buff := make([]byte, newLine)
n, err := input.Read(buff)
b, err := input.ReadByte()
if err != nil {
if err == io.EOF {
isEOF = true
break
} else {
return nil, fmt.Errorf("ReadByte: %v", err)
}
return nil, fmt.Errorf("Read: %v", err)
}
if n != newLine {
return nil, fmt.Errorf("Read: could not read enough bytes %d != %d", n, newLine)
if b == '\n' {
break
}
n, err = linebuf.Write(buff)
if err != nil {
return nil, fmt.Errorf("Write: %v", err)
if linebuf.Len() < maxLineCharacters {
linebuf.WriteByte(b)
} else if linebuf.Len() == maxLineCharacters {
curFile.IsIncomplete = true
}
if n != newLine {
return nil, fmt.Errorf("Write: could not write enough bytes %d != %d", n, newLine)
}
break
}
line := linebuf.String()

View File

@@ -11,28 +11,40 @@ import (
"strings"
"time"
"code.gitea.io/gitea/modules/log"
api "code.gitea.io/sdk/gitea"
"github.com/go-xorm/xorm"
)
// LFSLock represents a git lfs lock of repository.
type LFSLock struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX NOT NULL"`
Owner *User `xorm:"-"`
OwnerID int64 `xorm:"INDEX NOT NULL"`
Path string `xorm:"TEXT"`
Created time.Time `xorm:"created"`
ID int64 `xorm:"pk autoincr"`
Repo *Repository `xorm:"-"`
RepoID int64 `xorm:"INDEX NOT NULL"`
Owner *User `xorm:"-"`
OwnerID int64 `xorm:"INDEX NOT NULL"`
Path string `xorm:"TEXT"`
Created time.Time `xorm:"created"`
}
// BeforeInsert is invoked from XORM before inserting an object of this type.
func (l *LFSLock) BeforeInsert() {
l.OwnerID = l.Owner.ID
l.RepoID = l.Repo.ID
l.Path = cleanPath(l.Path)
}
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
func (l *LFSLock) AfterLoad() {
l.Owner, _ = GetUserByID(l.OwnerID)
func (l *LFSLock) AfterLoad(session *xorm.Session) {
var err error
l.Owner, err = getUserByID(session, l.OwnerID)
if err != nil {
log.Error(2, "LFS lock AfterLoad failed OwnerId[%d] not found: %v", l.OwnerID, err)
}
l.Repo, err = getRepositoryByID(session, l.RepoID)
if err != nil {
log.Error(2, "LFS lock AfterLoad failed RepoId[%d] not found: %v", l.RepoID, err)
}
}
func cleanPath(p string) string {
@@ -53,12 +65,12 @@ func (l *LFSLock) APIFormat() *api.LFSLock {
// CreateLFSLock creates a new lock.
func CreateLFSLock(lock *LFSLock) (*LFSLock, error) {
err := CheckLFSAccessForRepo(lock.Owner, lock.RepoID, "create")
err := CheckLFSAccessForRepo(lock.Owner, lock.Repo, AccessModeWrite)
if err != nil {
return nil, err
}
l, err := GetLFSLock(lock.RepoID, lock.Path)
l, err := GetLFSLock(lock.Repo, lock.Path)
if err == nil {
return l, ErrLFSLockAlreadyExist{lock.RepoID, lock.Path}
}
@@ -71,15 +83,15 @@ func CreateLFSLock(lock *LFSLock) (*LFSLock, error) {
}
// GetLFSLock returns release by given path.
func GetLFSLock(repoID int64, path string) (*LFSLock, error) {
func GetLFSLock(repo *Repository, path string) (*LFSLock, error) {
path = cleanPath(path)
rel := &LFSLock{RepoID: repoID}
rel := &LFSLock{RepoID: repo.ID}
has, err := x.Where("lower(path) = ?", strings.ToLower(path)).Get(rel)
if err != nil {
return nil, err
}
if !has {
return nil, ErrLFSLockNotExist{0, repoID, path}
return nil, ErrLFSLockNotExist{0, repo.ID, path}
}
return rel, nil
}
@@ -109,7 +121,7 @@ func DeleteLFSLockByID(id int64, u *User, force bool) (*LFSLock, error) {
return nil, err
}
err = CheckLFSAccessForRepo(u, lock.RepoID, "delete")
err = CheckLFSAccessForRepo(u, lock.Repo, AccessModeWrite)
if err != nil {
return nil, err
}
@@ -123,24 +135,15 @@ func DeleteLFSLockByID(id int64, u *User, force bool) (*LFSLock, error) {
}
//CheckLFSAccessForRepo check needed access mode base on action
func CheckLFSAccessForRepo(u *User, repoID int64, action string) error {
func CheckLFSAccessForRepo(u *User, repo *Repository, mode AccessMode) error {
if u == nil {
return ErrLFSLockUnauthorizedAction{repoID, "undefined", action}
}
mode := AccessModeRead
if action == "create" || action == "delete" || action == "verify" {
mode = AccessModeWrite
}
repo, err := GetRepositoryByID(repoID)
if err != nil {
return err
return ErrLFSUnauthorizedAction{repo.ID, "undefined", mode}
}
has, err := HasAccess(u.ID, repo, mode)
if err != nil {
return err
} else if !has {
return ErrLFSLockUnauthorizedAction{repo.ID, u.DisplayName(), action}
return ErrLFSUnauthorizedAction{repo.ID, u.DisplayName(), mode}
}
return nil
}

View File

@@ -298,10 +298,6 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
}()
headRepoPath := RepoPath(pr.HeadUserName, pr.HeadRepo.Name)
headGitRepo, err := git.OpenRepository(headRepoPath)
if err != nil {
return fmt.Errorf("OpenRepository: %v", err)
}
// Clone base repo.
tmpBasePath := path.Join(LocalCopyPath(), "merge-"+com.ToStr(time.Now().Nanosecond())+".git")
@@ -441,7 +437,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
return nil
}
l, err := headGitRepo.CommitsBetweenIDs(pr.MergedCommitID, pr.MergeBase)
l, err := baseGitRepo.CommitsBetweenIDs(pr.MergedCommitID, pr.MergeBase)
if err != nil {
log.Error(4, "CommitsBetweenIDs: %v", err)
return nil

View File

@@ -774,17 +774,17 @@ func UpdateLocalCopyBranch(repoPath, localPath, branch string) error {
return fmt.Errorf("git clone %s: %v", branch, err)
}
} else {
if err := git.Checkout(localPath, git.CheckoutOptions{
Branch: branch,
}); err != nil {
return fmt.Errorf("git checkout %s: %v", branch, err)
}
_, err := git.NewCommand("fetch", "origin").RunInDir(localPath)
if err != nil {
return fmt.Errorf("git fetch origin: %v", err)
}
if len(branch) > 0 {
if err := git.Checkout(localPath, git.CheckoutOptions{
Branch: branch,
}); err != nil {
return fmt.Errorf("git checkout %s: %v", branch, err)
}
if err := git.ResetHEAD(localPath, true, "origin/"+branch); err != nil {
return fmt.Errorf("git reset --hard origin/%s: %v", branch, err)
}
@@ -1579,11 +1579,25 @@ func ChangeRepositoryName(u *User, oldRepoName, newRepoName string) (err error)
return fmt.Errorf("GetRepositoryByName: %v", err)
}
// Change repository directory name.
if err = os.Rename(repo.RepoPath(), RepoPath(u.Name, newRepoName)); err != nil {
// Change repository directory name. We must lock the local copy of the
// repo so that we can atomically rename the repo path and updates the
// local copy's origin accordingly.
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
newRepoPath := RepoPath(u.Name, newRepoName)
if err = os.Rename(repo.RepoPath(), newRepoPath); err != nil {
return fmt.Errorf("rename repository directory: %v", err)
}
localPath := repo.LocalCopyPath()
if com.IsExist(localPath) {
_, err := git.NewCommand("remote", "set-url", "origin", newRepoPath).RunInDir(localPath)
if err != nil {
return fmt.Errorf("git remote set-url origin %s: %v", newRepoPath, err)
}
}
wikiPath := repo.WikiPath()
if com.IsExist(wikiPath) {
if err = os.Rename(wikiPath, WikiPath(u.Name, newRepoName)); err != nil {

View File

@@ -20,6 +20,7 @@ import (
"code.gitea.io/gitea/modules/util"
api "code.gitea.io/sdk/gitea"
"github.com/Unknwon/com"
gouuid "github.com/satori/go.uuid"
)
@@ -587,8 +588,8 @@ func (t *HookTask) deliver() {
Header("X-Gitea-Event", string(t.EventType)).
Header("X-Gogs-Delivery", t.UUID).
Header("X-Gogs-Event", string(t.EventType)).
Header("X-GitHub-Delivery", t.UUID).
Header("X-GitHub-Event", string(t.EventType)).
HeaderWithSensitiveCase("X-GitHub-Delivery", t.UUID).
HeaderWithSensitiveCase("X-GitHub-Event", string(t.EventType)).
SetTLSClientConfig(&tls.Config{InsecureSkipVerify: setting.Webhook.SkipTLSVerify})
switch t.ContentType {
@@ -677,9 +678,15 @@ func DeliverHooks() {
}
// Start listening on new hook requests.
for repoID := range HookQueue.Queue() {
log.Trace("DeliverHooks [repo_id: %v]", repoID)
HookQueue.Remove(repoID)
for repoIDStr := range HookQueue.Queue() {
log.Trace("DeliverHooks [repo_id: %v]", repoIDStr)
HookQueue.Remove(repoIDStr)
repoID, err := com.StrTo(repoIDStr).Int64()
if err != nil {
log.Error(4, "Invalid repo ID: %s", repoIDStr)
continue
}
tasks = make([]*HookTask, 0, 5)
if err := x.Where("repo_id=? AND is_delivered=?", repoID, false).Find(&tasks); err != nil {

View File

@@ -189,7 +189,9 @@ func Contexter() macaron.Handler {
branchName = repo.DefaultBranch
}
prefix := setting.AppURL + path.Join(ownerName, repoName, "src", "branch", branchName)
c.PlainText(http.StatusOK, []byte(com.Expand(`
c.Header().Set("Content-Type", "text/html")
c.WriteHeader(http.StatusOK)
c.Write([]byte(com.Expand(`<!doctype html>
<html>
<head>
<meta name="go-import" content="{GoGetImport} git {CloneLink}">

View File

@@ -164,6 +164,12 @@ func (r *Request) Header(key, value string) *Request {
return r
}
// HeaderWithSensitiveCase add header item in request and keep the case of the header key.
func (r *Request) HeaderWithSensitiveCase(key, value string) *Request {
r.req.Header[key] = []string{value}
return r
}
// Headers returns headers in request.
func (r *Request) Headers() http.Header {
return r.req.Header

View File

@@ -13,24 +13,35 @@ import (
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/sdk/gitea"
"gopkg.in/macaron.v1"
)
func checkRequest(req macaron.Request, post bool) int {
//checkIsValidRequest check if it a valid request in case of bad request it write the response to ctx.
func checkIsValidRequest(ctx *context.Context, post bool) bool {
if !setting.LFS.StartServer {
return 404
writeStatus(ctx, 404)
return false
}
if !MetaMatcher(req) {
return 400
if !MetaMatcher(ctx.Req) {
writeStatus(ctx, 400)
return false
}
if !ctx.IsSigned {
user, _, _, err := parseToken(ctx.Req.Header.Get("Authorization"))
if err != nil {
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
writeStatus(ctx, 401)
return false
}
ctx.User = user
}
if post {
mediaParts := strings.Split(req.Header.Get("Content-Type"), ";")
mediaParts := strings.Split(ctx.Req.Header.Get("Content-Type"), ";")
if mediaParts[0] != metaMediaType {
return 400
writeStatus(ctx, 400)
return false
}
}
return 200
return true
}
func handleLockListOut(ctx *context.Context, lock *models.LFSLock, err error) {
@@ -59,17 +70,16 @@ func handleLockListOut(ctx *context.Context, lock *models.LFSLock, err error) {
// GetListLockHandler list locks
func GetListLockHandler(ctx *context.Context) {
status := checkRequest(ctx.Req, false)
if status != 200 {
writeStatus(ctx, status)
if !checkIsValidRequest(ctx, false) {
return
}
ctx.Resp.Header().Set("Content-Type", metaMediaType)
err := models.CheckLFSAccessForRepo(ctx.User, ctx.Repo.Repository.ID, "list")
err := models.CheckLFSAccessForRepo(ctx.User, ctx.Repo.Repository, models.AccessModeRead)
if err != nil {
if models.IsErrLFSLockUnauthorizedAction(err) {
ctx.JSON(403, api.LFSLockError{
if models.IsErrLFSUnauthorizedAction(err) {
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
ctx.JSON(401, api.LFSLockError{
Message: "You must have pull access to list locks : " + err.Error(),
})
return
@@ -96,7 +106,7 @@ func GetListLockHandler(ctx *context.Context) {
path := ctx.Query("path")
if path != "" { //Case where we request a specific id
lock, err := models.GetLFSLock(ctx.Repo.Repository.ID, path)
lock, err := models.GetLFSLock(ctx.Repo.Repository, path)
handleLockListOut(ctx, lock, err)
return
}
@@ -120,9 +130,7 @@ func GetListLockHandler(ctx *context.Context) {
// PostLockHandler create lock
func PostLockHandler(ctx *context.Context) {
status := checkRequest(ctx.Req, true)
if status != 200 {
writeStatus(ctx, status)
if !checkIsValidRequest(ctx, false) {
return
}
ctx.Resp.Header().Set("Content-Type", metaMediaType)
@@ -136,9 +144,9 @@ func PostLockHandler(ctx *context.Context) {
}
lock, err := models.CreateLFSLock(&models.LFSLock{
RepoID: ctx.Repo.Repository.ID,
Path: req.Path,
Owner: ctx.User,
Repo: ctx.Repo.Repository,
Path: req.Path,
Owner: ctx.User,
})
if err != nil {
if models.IsErrLFSLockAlreadyExist(err) {
@@ -148,8 +156,9 @@ func PostLockHandler(ctx *context.Context) {
})
return
}
if models.IsErrLFSLockUnauthorizedAction(err) {
ctx.JSON(403, api.LFSLockError{
if models.IsErrLFSUnauthorizedAction(err) {
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
ctx.JSON(401, api.LFSLockError{
Message: "You must have push access to create locks : " + err.Error(),
})
return
@@ -164,18 +173,16 @@ func PostLockHandler(ctx *context.Context) {
// VerifyLockHandler list locks for verification
func VerifyLockHandler(ctx *context.Context) {
status := checkRequest(ctx.Req, true)
if status != 200 {
writeStatus(ctx, status)
if !checkIsValidRequest(ctx, false) {
return
}
ctx.Resp.Header().Set("Content-Type", metaMediaType)
err := models.CheckLFSAccessForRepo(ctx.User, ctx.Repo.Repository.ID, "verify")
err := models.CheckLFSAccessForRepo(ctx.User, ctx.Repo.Repository, models.AccessModeWrite)
if err != nil {
if models.IsErrLFSLockUnauthorizedAction(err) {
ctx.JSON(403, api.LFSLockError{
if models.IsErrLFSUnauthorizedAction(err) {
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
ctx.JSON(401, api.LFSLockError{
Message: "You must have push access to verify locks : " + err.Error(),
})
return
@@ -211,9 +218,7 @@ func VerifyLockHandler(ctx *context.Context) {
// UnLockHandler delete locks
func UnLockHandler(ctx *context.Context) {
status := checkRequest(ctx.Req, true)
if status != 200 {
writeStatus(ctx, status)
if !checkIsValidRequest(ctx, false) {
return
}
ctx.Resp.Header().Set("Content-Type", metaMediaType)
@@ -228,8 +233,9 @@ func UnLockHandler(ctx *context.Context) {
lock, err := models.DeleteLFSLockByID(ctx.ParamsInt64("lid"), ctx.User, req.Force)
if err != nil {
if models.IsErrLFSLockUnauthorizedAction(err) {
ctx.JSON(403, api.LFSLockError{
if models.IsErrLFSUnauthorizedAction(err) {
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
ctx.JSON(401, api.LFSLockError{
Message: "You must have push access to delete locks : " + err.Error(),
})
return

View File

@@ -473,7 +473,6 @@ func logRequest(r macaron.Request, status int) {
// authenticate uses the authorization string to determine whether
// or not to proceed. This server assumes an HTTP Basic auth format.
func authenticate(ctx *context.Context, repository *models.Repository, authorization string, requireWrite bool) bool {
accessMode := models.AccessModeRead
if requireWrite {
accessMode = models.AccessModeWrite
@@ -482,86 +481,92 @@ func authenticate(ctx *context.Context, repository *models.Repository, authoriza
if !repository.IsPrivate && !requireWrite {
return true
}
if ctx.IsSigned {
accessCheck, _ := models.HasAccess(ctx.User.ID, repository, accessMode)
return accessCheck
}
if authorization == "" {
user, repo, opStr, err := parseToken(authorization)
if err != nil {
return false
}
if authenticateToken(repository, authorization, requireWrite) {
ctx.User = user
if opStr == "basic" {
accessCheck, _ := models.HasAccess(ctx.User.ID, repository, accessMode)
return accessCheck
}
if repository.ID == repo.ID {
if requireWrite && opStr != "upload" {
return false
}
return true
}
if !strings.HasPrefix(authorization, "Basic ") {
return false
}
c, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(authorization, "Basic "))
if err != nil {
return false
}
cs := string(c)
i := strings.IndexByte(cs, ':')
if i < 0 {
return false
}
user, password := cs[:i], cs[i+1:]
userModel, err := models.GetUserByName(user)
if err != nil {
return false
}
if !userModel.ValidatePassword(password) {
return false
}
accessCheck, _ := models.HasAccess(userModel.ID, repository, accessMode)
return accessCheck
return false
}
func authenticateToken(repository *models.Repository, authorization string, requireWrite bool) bool {
if !strings.HasPrefix(authorization, "Bearer ") {
return false
func parseToken(authorization string) (*models.User, *models.Repository, string, error) {
if authorization == "" {
return nil, nil, "unknown", fmt.Errorf("No token")
}
token, err := jwt.Parse(authorization[7:], func(t *jwt.Token) (interface{}, error) {
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"])
if strings.HasPrefix(authorization, "Bearer ") {
token, err := jwt.Parse(authorization[7:], func(t *jwt.Token) (interface{}, error) {
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"])
}
return setting.LFS.JWTSecretBytes, nil
})
if err != nil {
return nil, nil, "unknown", err
}
return setting.LFS.JWTSecretBytes, nil
})
if err != nil {
return false
}
claims, claimsOk := token.Claims.(jwt.MapClaims)
if !token.Valid || !claimsOk {
return false
claims, claimsOk := token.Claims.(jwt.MapClaims)
if !token.Valid || !claimsOk {
return nil, nil, "unknown", fmt.Errorf("Token claim invalid")
}
opStr, ok := claims["op"].(string)
if !ok {
return nil, nil, "unknown", fmt.Errorf("Token operation invalid")
}
repoID, ok := claims["repo"].(float64)
if !ok {
return nil, nil, opStr, fmt.Errorf("Token repository id invalid")
}
r, err := models.GetRepositoryByID(int64(repoID))
if err != nil {
return nil, nil, opStr, err
}
userID, ok := claims["user"].(float64)
if !ok {
return nil, r, opStr, fmt.Errorf("Token user id invalid")
}
u, err := models.GetUserByID(int64(userID))
if err != nil {
return nil, r, opStr, err
}
return u, r, opStr, nil
}
opStr, ok := claims["op"].(string)
if !ok {
return false
if strings.HasPrefix(authorization, "Basic ") {
c, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(authorization, "Basic "))
if err != nil {
return nil, nil, "basic", err
}
cs := string(c)
i := strings.IndexByte(cs, ':')
if i < 0 {
return nil, nil, "basic", fmt.Errorf("Basic auth invalid")
}
user, password := cs[:i], cs[i+1:]
u, err := models.GetUserByName(user)
if err != nil {
return nil, nil, "basic", err
}
if !u.ValidatePassword(password) {
return nil, nil, "basic", fmt.Errorf("Basic auth failed")
}
return u, nil, "basic", nil
}
if requireWrite && opStr != "upload" {
return false
}
repoID, ok := claims["repo"].(float64)
if !ok {
return false
}
if repository.ID != int64(repoID) {
return false
}
return true
return nil, nil, "unknown", fmt.Errorf("Token not found")
}
func requireAuth(ctx *context.Context) {

View File

@@ -43,7 +43,7 @@ var (
IssueAlphanumericPattern = regexp.MustCompile(`( |^|\()[A-Z]{1,10}-[1-9][0-9]*\b`)
// CrossReferenceIssueNumericPattern matches string that references a numeric issue in a different repository
// e.g. gogits/gogs#12345
CrossReferenceIssueNumericPattern = regexp.MustCompile(`( |^)[0-9a-zA-Z]+/[0-9a-zA-Z]+#[0-9]+\b`)
CrossReferenceIssueNumericPattern = regexp.MustCompile(`( |^)[0-9a-zA-Z-_\.]+/[0-9a-zA-Z-_\.]+#[0-9]+\b`)
// Sha1CurrentPattern matches string that represents a commit SHA, e.g. d8a994ef243349f321568f9e36d5c3f444b99cae
// Although SHA1 hashes are 40 chars long, the regex matches the hash from 7 to 40 chars in length

View File

@@ -285,6 +285,9 @@ func TestRender_CrossReferences(t *testing.T) {
test(
"gogits/gogs#12345",
`<p><a href="`+URLJoin(AppURL, "gogits", "gogs", "issues", "12345")+`" rel="nofollow">gogits/gogs#12345</a></p>`)
test(
"go-gitea/gitea#12345",
`<p><a href="`+URLJoin(AppURL, "go-gitea", "gitea", "issues", "12345")+`" rel="nofollow">go-gitea/gitea#12345</a></p>`)
}
func TestRender_FullIssueURLs(t *testing.T) {

View File

@@ -38,6 +38,7 @@ Joel da Rosa <webjoel AT hotmail DOT com>
Joubert RedRat <me+github AT redrat DOT com DOT br>
Jonathan Lozada De La Matta <jlozada2426 AT protonmail DOT com>
Juraj Bubniak <contact AT jbub DOT eu>
Kazuki Sawada <kazuki AT 6715 DOT jp>
Lafriks <lafriks AT gmail DOT com>
Lauri Ojansivu <x AT xet7 DOT org>
Luc Stepniewski <luc AT stepniewski DOT fr>

View File

@@ -71,6 +71,7 @@ db_name=Nombre de la base de datos
db_helper=Por favor, utiliza el motor INNODB con la codificación de caracteres utf8_general_ci para MySQL.
ssl_mode=Modo SSL
path=Ruta
sqlite_helper=Ruta del archivo a la base de datos SQLite3 o TiDB. <br>Utilice la ruta absoluta al iniciar como servicio.
err_empty_db_path=La ruta a la base de datos SQLite3 o TiDB no puede estar vacía.
err_invalid_tidb_name=El nombre de la base de datos TiDB no puede contener los caracteres "." ni "-".
no_admin_and_disable_registration=No puede deshabilitar el registro sin crear una cuenta de administrador.
@@ -82,14 +83,17 @@ app_name_helper=Usted puede poner su nombre de la organización aquí.
repo_path=Ruta del repositorio de Raiz (Root)
repo_path_helper=Todos los repositorios remotos de Git se guardarán en este directorio.
lfs_path=Ruta raíz LFS
lfs_path_helper=Los archivos almacenados con Git LFS, se almacenarán en este directorio. Dejar vacío para deshabilitar LFS.
run_user=Ejecutar como Usuario
run_user_helper=El usuario necesita tener acceso a la Ruta Raíz del Repositorio y ejecutar Gitea.
domain=Dominio
domain_helper=Esto afecta a las URLs para clonar por SSH.
ssh_port=Puerto SSH
ssh_port_helper=Número de puerto que está usando su servidor SSH. Dejar vacío para deshabilitar.
http_port=Puerto HTTP
http_port_helper=Puerto en el que escuchará la aplicación.
app_url=URL de la aplicación
app_url_helper=Esto afecta al clon URL de HTTP/HTTPS y algunas notificaciones de correo electrónico.
log_root_path=Ruta del registro
log_root_path_helper=Directorio donde almacenar los registros.
@@ -97,6 +101,7 @@ optional_title=Configuración opcional
email_title=Configuración del servicio de correo
smtp_host=Servidor SMTP
smtp_from=Desde
smtp_from_helper=Remitente de email, RFC 5322. Puede ser solamente una dirección de correo electrónico, o estar en el formato "Nombre" <email@example.com>.
mailer_user=Usuario remitente
mailer_password=Contraseña del Remitente
register_confirm=Habilitar la Confirmación en el Registro
@@ -111,6 +116,7 @@ federated_avatar_lookup_popup=Habilitar búsqueda de avatares federador para usa
disable_registration=Desactivar Auto-Registro
disable_registration_popup=Desactivar auto-registro del usuario, solo el administrador podrá crear cuentas nuevas.
openid_signin_popup=Activar inicio de sesión vía OpenID
openid_signup_popup=Habilitar auto-registro basado en OpenID
enable_captcha=Activar Captcha
enable_captcha_popup=Requerir CAPTCHA para auto-registro de usuario.
require_sign_in_view=Activar el Inicio de Sesión obligatorio para Ver Páginas
@@ -133,7 +139,11 @@ install_success=¡Bienvenido! Gracias por elegir Gitea. Diviértete. Y, ¡cuidat
invalid_log_root_path=La ruta para los registros es inválida: %v
default_keep_email_private=Valor por defecto para guardar correo electrónico privado
default_keep_email_private_popup=Este es el valor predeterminado para la visibilidad de la dirección de correo electrónico del usuario. Si establecido en true, la dirección de correo electrónico de todos los nuevos usuarios se ocultará hasta que el usuario cambia su configuración.
default_allow_create_organization=Valor de permiso predeterminado para que nuevos usuarios creen organizaciones
default_allow_create_organization_popup=Este es el valor del permiso predeterminado que se asignará a los nuevos usuarios. Si es establecido en "activado", los nuevos usuarios podrán crear Organizaciones.
default_enable_timetracking_popup=Los repositorios tendrán habilitado el seguimiento de tiempo por defecto, según esta configuración
no_reply_address=Dirección de no respuesta
no_reply_address_helper=El dominio para la dirección de correo electrónico en los registros del git, si el usuario mantiene su dirección de correo electrónico en privado. Por ejemplo, el usuario 'Juan' y 'noreply.example.org' será 'joe@noreply.example.org'
[home]
uname_holder=Nombre de usuario o correo electrónico
@@ -168,9 +178,12 @@ remember_me=Recuérdame
forgot_password_title=He olvidado mi contraseña
forgot_password=¿Has olvidado tu contraseña?
sign_up_now=¿Necesitas una cuenta? Regístrate ahora.
confirmation_mail_sent_prompt=Un nuevo correo de confirmación se ha enviado a <b>%s</b>. Comprueba tu bandeja de entrada en las siguientes %s para completar el registro.
reset_password_mail_sent_prompt=Un correo de confirmación se ha enviado a <b>%s</b>. Comprueba tu bandeja de entrada en las siguientes %s para completar el reinicio de contraseña.
active_your_account=Activa tu cuenta
prohibit_login=Ingreso prohibido
prohibit_login_desc=Su cuenta tiene prohibido ingresar al sistema, fovor contactar al administrador del sistema.
resent_limit_prompt=Estás solicitando el reenvío del email de activación con demasiada frecuencia. Espera 3 minutos.
has_unconfirmed_mail=Hola %s, tu correo electrónico (<b>%s</b>) no está confirmado. Si no has recibido un correo de confirmación o necesitas que lo enviemos de nuevo, por favor, haz click en el siguiente botón.
resend_mail=Haz click aquí para reenviar tu correo electrónico de activación
email_not_associate=Esta dirección de correo electrónico no esta asociada a ninguna cuenta.
@@ -179,13 +192,20 @@ reset_password=Restablecer su contraseña
invalid_code=Lo sentimos, tu código de confirmación ha expirado o no es válido.
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.
non_local_account=Las cuentas no locales no pueden cambiar las contraseñas a través de la interfaz web de Gitea.
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_passcode_incorrect=Su contraseña es incorrecta. Si extravió el dispositivo, use su código de cero para iniciar sesión.
twofa_scratch_token_incorrect=El código cero es incorrecto.
login_userpass=Usuario / contraseña
login_openid=OpenID
openid_connect_submit=Conectar
openid_connect_title=Accede con una cuenta existente
openid_connect_desc=El sistema no reconoce los URI OpenID elegidos, puede anexarlo a una cuenta existente.
openid_register_title=Crear una nueva cuenta
openid_register_desc=El sistema no conoce los OpenID URI elegidos, puede asociarlos a una nueva cuenta aquí.
openid_signin_desc=URIs de ejemplo: https://anne.me, bob.openid.org.cn, gnusocial.net/carry
disable_forgot_password_mail=Se ha desactivado el restablecimiento de contraseña. Contacte al administrador del sitio.
[mail]
activate_account=Por favor, active su cuenta
@@ -220,6 +240,8 @@ TreeName=Ruta del archivo
Content=Contenido
require_error=` no puede estar vacío.`
alpha_dash_error=`deben ser caracteres alfanuméricos válidos o guiones (-_). `
alpha_dash_dot_error=` deben ser caracteres válidos alfanuméricos, guiones (-_) o puntos. `
size_error=` debe ser de tamaño %s.`
min_size_error=` debe contener al menos %s caracteres.`
max_size_error=` debe contener como máximo %s caracteres.`
@@ -241,6 +263,7 @@ username_password_incorrect=Nombre de usuario o contraseña incorrectos.
enterred_invalid_repo_name=Por favor, asegúrate de que has introducido el nombre correctamente.
enterred_invalid_owner_name=Por favor, asegúrate de que el nombre del propietario introducido es correcto.
user_not_exist=Este usuario no existe.
last_org_owner=No está permitido quitar el último propietario del equipo, porque siempre debe haber al menos un propietario en una organización determinada.
cannot_add_org_to_team=Organización no puede agregarse como un miembro del equipo.
invalid_ssh_key=Lo sentimos, no hemos podido verificar tu clave SSH: %s
@@ -336,10 +359,15 @@ add_email_success=Tu nuevo correo electrónico se ha añadido correctamente.
add_openid_success=Su nueva dirección de OpenID se ha agregado correctamente.
keep_email_private=Mantener la dirección de correo electrónico privada
keep_email_private_popup=Si activa esta opción se ocultará su dirección de correo electrónico a otros usuarios.
openid_desc=Sus direcciones OpenID le permitirán delegar autenticación a su proveedor de elección
manage_ssh_keys=Gestionar Claves SSH
manage_gpg_keys=Administrar claves GPG
add_key=Añadir Clave
ssh_desc=Estas son las claves SSH asociadas con su cuenta. Debido a que estas teclas permiten que cualquier persona que las utilice, acceder a los repositorios, es muy importante que se asegúrese que reconocerlas.
gpg_desc=Estas son las claves GPG asociadas con su cuenta. Debido a que estas teclas permiten que las colaboraciones sean verificadas, es muy importante que mantenga segura la clave privada correspondiente.
ssh_helper=<strong>¿Necesitas ayuda?</strong> Echa un vistazo en la guía de GitHub para <a href="%s">crear tus propias claves SSH</a> o resolver <a href="%s">problemas comunes</a> que puede encontrar al usar SSH.
gpg_helper=<strong>¿Necesitas ayuda?</strong> Echa un vistazo en la guía de GitHub <a href="%s">sobre GPG</a>.
add_new_key=Añadir clave SSH
add_new_gpg_key=Añadir clave GPG
ssh_key_been_used=Ya se ha utilizado esta clave pública.
@@ -356,6 +384,7 @@ delete_key=Eliminar
ssh_key_deletion=Borrado de Clave SSH
gpg_key_deletion=Eliminación de claves GPG
ssh_key_deletion_desc=Al eliminar esta clave SSH, revocarás todo acceso utilizando esta clave SSH para tu cuenta. ¿Quieres continuar?
gpg_key_deletion_desc=Eliminar esta clave GPG des-verificará todas las colaboraciones firmadas con esta clave GPG. ¿Seguro que desea continuar?
ssh_key_deletion_success=La clave SSH ha sido eliminada.
gpg_key_deletion_success=La clave GPG ha sido eliminada.
add_on=Añadido en
@@ -363,12 +392,16 @@ valid_until=Válido hasta
valid_forever=Válido para siempre
last_used=Utilizado por última vez en
no_activity=No hay actividad reciente
can_read_info=Leer
can_write_info=Escribir
key_state_desc=Esta clave ha sido usada en los últimos 7 días
token_state_desc=Este token ha sido utilizado en los últimos 7 días
show_openid=Mostrar mi perfil
hide_openid=Esconderse de perfil
ssh_disabled=SSH está desactivado
manage_social=Gestionar Redes Sociales asociadas
social_desc=Esta es una lista cuentas sociales asociadas. Por razones de seguridad, asegúrese de que reconoce todas estas entradas, ya que puede ser utilizadas para iniciar sesión en su cuenta.
unbind=Desvincular
unbind_success=Cuenta social ha sido independiente desde su cuenta.
@@ -378,17 +411,27 @@ tokens_desc=Tokens generados que pueden ser usados para acceder al API de Gitea.
new_token_desc=Desde ahora, todos los tokens tendrán acceso completo a tu cuenta.
token_name=Nombre del Token
generate_token=Generar Token
generate_token_success=Su token de acceso fue generado con éxito. Asegúrese de copiarlo ahora, no será capaz de hacerlo más adelante.
delete_token=Eliminar
access_token_deletion=Borrado de Token de Acceso Personal
access_token_deletion_desc=Borrar este token de acceso personal, revocará el acceso de cualquier aplicación que use este token. ¿Desea continuar?
delete_token_success=El token de acceso personal ha sido eliminado. No olvide actualizar cualquier aplicación que use este token.
twofa_desc=Gitea admite la autenticación de dos factores para mejorar la seguridad de su cuenta.
twofa_is_enrolled=Su cuenta actualmente está <strong>registrada</strong> en la autenticación de dos factores.
twofa_not_enrolled=Tu cuenta no está actualmente inscrita en la autenticación de doble factor.
twofa_disable=Deshabilitar autenticación en dos pasos
twofa_scratch_token_regenerated=Tu token ha sido regenerado. Ahora es %s. Guárdelo en un lugar seguro.
twofa_enroll=Habilitar autenticación en dos pasos
twofa_disable_note=Si es necesario, puede deshabilitar la autenticación en dos pasos.
twofa_disable_desc=Deshabilitar la autenticación de dos factores hará que su cuenta sea menos segura. ¿Seguro que desea continuar?
regenerate_scratch_token_desc=Si extravió su token, o ya lo usó para iniciar sesión, puede restablecerlo aquí.
twofa_disabled=La autenticación en dos pasos ha sido deshabilitada.
scan_this_image=Analiza esta imagen con la aplicación de autenticación:
or_enter_secret=O introduzca el secreto: %s
then_enter_passcode=Y use el código de acceso que la aplicación le dio:
passcode_invalid=Esa contraseña no es válido. Vuelve a intentarlo.
twofa_enrolled=Su cuenta ha sido vinculada con autenticación de dos factores. Asegúrese de guardar su ficha de scratch (%s), ya que sólo aparecerá una vez.
manage_account_links=Gestionar los vínculos de la cuenta
manage_account_links_desc=Cuentas externas vinculadas a esta cuenta
@@ -429,14 +472,20 @@ auto_init=Inicializar los archivos seleccionados y plantillas de este repositori
create_repo=Crear repositorio
default_branch=Rama por defecto
mirror_prune=Purgar
mirror_prune_desc=Elimine cualquier referencia de seguimiento remota, que ya no exista
mirror_interval=Intervalo de copia de seguridad (unidades de tiempo válidas: "h", "m", "s")
mirror_address=Dirección de la réplica
mirror_address_desc=Por favor, incluya las credenciales de usuario necesarias en la dirección.
mirror_last_synced=Última sincronización
watchers=Seguidores
stargazers=Fans
forks=Forks
pick_reaction=Escoge tu reacción
reactions_more=y %d más
form.reach_limit_of_creation=Ya han alcanzado su límite de repositorios de %d.
form.name_reserved=El nombre de repositorio '%s' está reservado.
form.name_pattern_not_allowed=El nombre del repositorio '%s' no está permitido.
need_auth=Requiere autorización
migrate_type=Tipo de migración
@@ -448,9 +497,11 @@ migrate.clone_local_path=o ruta del servidor local
migrate.permission_denied=No te está permitido importar repositorios locales.
migrate.invalid_local_path=Rutal local inválida, no existe o no es un directorio.
migrate.failed=Migración fallida: %v
migrate.lfs_mirror_unsupported=La duplicación de objetos LFS no es compatible; utilice 'git lfs fetch --all' y 'git lfs push  en su lugar.
mirror_from=espejo de
forked_from=forked de
fork_from_self=No puedes hacer "fork" a un repositorio que ya tienes.
copy_link=Copiar
copy_link_success=¡Copiado!
copy_link_error=Presione ⌘ + C o Ctrl-C para copiar
@@ -459,6 +510,7 @@ unwatch=Dejar de seguir
watch=Seguir
unstar=Eliminar destacado
star=Destacar
fork=Cuchillo
download_archive=Descargar este repositorio
no_desc=Sin descripción
@@ -485,11 +537,13 @@ file_view_raw=Ver original
file_permalink=Enlace permanente
file_too_large=Este archivo es demasiado grande para ser mostrado
video_not_supported_in_browser=Tu navegador no soporta el tag video de HTML5.
stored_lfs=Almacenados con Git LFS
editor.new_file=Nuevo archivo
editor.upload_file=Subir archivo
editor.edit_file=Editar archivo
editor.preview_changes=Vista previa de los cambios
editor.cannot_edit_non_text_files=No se pueden editar archivos binarios desde la interfaz web
editor.edit_this_file=Editar este archivo
editor.must_be_on_a_branch=Debes estar en una rama para hacer o proponer cambios en este archivo
editor.fork_before_edit=Debes hacer un fork de este repositorio antes de editar el archivo
@@ -516,6 +570,7 @@ editor.directory_is_a_file=La entrada '%s' en el directorio padre es un archivo
editor.file_is_a_symlink=El archivo '%s' es un enlace simbólico que no puede ser modificado desde el editor web
editor.filename_is_a_directory=El nombre del fichero '%s' es un directorio existente en este repositorio.
editor.file_editing_no_longer_exists=El archivo '%s' que estás editando ya no existe en este repositorio.
editor.file_changed_while_editing=Desde que comenzó a editar, el contenido del archivo ha sido cambiado. <a target="_blank" rel="noopener" href="%s">Clic aquí</a> para ver qué ha cambiado o <strong>presione confirmar de nuevo</strong> para sobrescribir los cambios.
editor.file_already_exists=Ya existe un archivo con nombre '%s' en este repositorio.
editor.no_changes_to_show=No existen cambios para mostrar.
editor.fail_to_update_file=Error al actualizar/crear el archivo '%s', error: %v
@@ -534,6 +589,7 @@ commits.message=Mensaje
commits.date=Fecha
commits.older=Anterior
commits.newer=Posterior
commits.signed_by=Firmado por
commits.gpg_key_id=ID clave GPG
@@ -555,12 +611,19 @@ issues.new_label=Nueva Etiqueta
issues.new_label_placeholder=Nombre etiqueta...
issues.create_label=Crear etiqueta
issues.label_templates.title=Carga un conjunto predefinido de etiquetas
issues.label_templates.info=Todavía no hay ninguna etiqueta. Puede hacer clic en el botón "Nueva Etiqueta" debajo, para crear uno o utilizar un conjunto predefinido.
issues.label_templates.helper=Seleccionar un conjunto de etiquetas
issues.label_templates.use=Usar este conjunto de etiquetas
issues.label_templates.fail_to_load_file=Error al cargar el archivo de plantilla de etiqueta '%s': %v
issues.add_label_at=añadida la etiqueta <div class="ui label" style="color: %s\; background-color: %s">%s</div> %s
issues.remove_label_at=eliminada la etiqueta <div class="ui label" style="color: %s\; background-color: %s">%s</div> %s
issues.add_milestone_at=`agregado esto al <b>%s</b> hito %s '
issues.change_milestone_at=` modificó el hito de <b>%s</b> to <b>%s</b> %s`
issues.remove_milestone_at=`eliminado esto del <b>%s</b> hito %s '
issues.deleted_milestone=`(eliminado)`
issues.self_assign_at=`auto asignado este %s`
issues.add_assignee_at='fue asignado por <b>%s</b> %s'
issues.change_title_at=`título cambiado de <b>%s</b> a <b>%s</b> %s`
issues.delete_branch_at=`rama eliminada <b>%s</b> %s`
issues.open_tab=%d abiertas
issues.close_tab=%d cerradas
@@ -585,6 +648,7 @@ issues.filter_sort.leastcomment=Menos comentadas
issues.action_open=Abrir
issues.action_close=Cerrar
issues.action_label=Etiqueta
issues.action_milestone=Hito
issues.action_assignee=Asignado a
issues.action_assignee_no_select=Sin asignado
issues.opened_by=abierta %[1]s por <a href="%[2]s">%[3]s</a>
@@ -620,6 +684,8 @@ issues.label_edit=Editar
issues.label_delete=Borrar
issues.label_modify=Edición de Etiqueta
issues.label_deletion=Borrado de Etiqueta
issues.label_deletion_desc=Eliminar esta etiqueta la eliminará de todos los problemas reportados. ¿Seguro que quiere continuar?
issues.label_deletion_success=La etiqueta ha sido eliminada exitosamente.
issues.label.filter_sort.alphabetically=Alfabéticamente
issues.label.filter_sort.by_size=Tamaño
issues.label.filter_sort.reverse_by_size=Tamaño reversa
@@ -628,6 +694,7 @@ issues.attachment.open_tab='Haga clic para ver "%s" en una pestaña nueva'
issues.attachment.download=`Haga clic para descargar "%s"`
issues.subscribe=Suscribir
issues.unsubscribe=Desuscribirse
issues.tracking_already_started='Ya has comenzado el tiempo de seguimiento en este <a href="%s">tema</a>!'
issues.add_time_hours=Horas
issues.add_time_minutes=Minutos
issues.cancel_tracking=Cancelar
@@ -648,12 +715,15 @@ pulls.merged_title_desc=fusionados %[1]d commits de <code>%[2]s</code> en <code>
pulls.tab_conversation=Conversación
pulls.tab_commits=Commits
pulls.tab_files=Archivos modificados
pulls.reopen_to_merge=Vuelva a abrir la solicitud de "pull" para realizar una fusión.
pulls.merged=Fusionado
pulls.data_broken=Los datos de este pull request ya no están disponibles porque se ha eliminado la información del fork.
pulls.is_checking=Se está procediendo a la búsqueda de conflictos, por favor actualice la página en unos momentos.
pulls.can_auto_merge_desc=Este Pull Request puede ser fusionado automáticamente.
pulls.cannot_auto_merge_desc=Hay conflictos con esta solicitud de extracción, no se puede fusionar automáticamente.
pulls.cannot_auto_merge_helper=Por favor, fusiona manualmente para resolver los conflictos.
pulls.merge_pull_request=Fusionar Pull Request
pulls.open_unmerged_pull_exists=No puede realizar volver a abrir la operación porque ya hay una solicitud de extracción abierta (#%d) del mismo repositorio con, la misma información a la espera.
milestones.new=Nuevo hito
milestones.open_tab=%d abiertas
@@ -671,10 +741,12 @@ milestones.clear=Limpiar
milestones.invalid_due_date_format=El formato de la fecha límite no es válido, debe ser 'yyyy-mm-dd'.
milestones.create_success=¡El milestone '%s' ha sido creado con éxito!
milestones.edit=Editar Milestone
milestones.edit_subheader=Use una buena descripción para los hitos, para que las personas no se confundan.
milestones.cancel=Cancelar
milestones.modify=Modificar Milestone
milestones.edit_success=¡Los cambios al milestone '%s' se han guardado con éxito!
milestones.deletion=Borrar milestone
milestones.deletion_desc=Al eliminar este hito, lo eliminará de todos los problemas relacionados. ¿Quieres continuar?
milestones.deletion_success=¡El milestone ha sido eliminado con éxito!
milestones.filter_sort.most_complete=Más completa
milestones.filter_sort.most_issues=Mayoría de los problemas
@@ -683,16 +755,21 @@ milestones.filter_sort.least_issues=Menos problemas
wiki=Wiki
wiki.welcome=Bienvenidos a la wiki del proyecto
wiki.welcome_desc=Una wiki le permite a usted y sus colaboradores fácilmente documentar su proyecto.
wiki.desc=La wiki es un lugar para almacenar documentación
wiki.create_first_page=Crear la primera página
wiki.page=Página
wiki.filter_page=Filtrar página
wiki.new_page=Crear nueva página
wiki.default_commit_message=Escriba una nota acerca de la actualización de esta página (opcional).
wiki.save_page=Guardar página
wiki.last_commit_info=%s editó esta página %s
wiki.edit_page_button=Editar
wiki.new_page_button=Nueva página
wiki.delete_page_button=Eliminar página
wiki.delete_page_notice_1=Esto eliminará la página <code>"%s"</code>. Asegúrese de querer eliminar esta página.
wiki.page_already_exists=Ya existe una página con el mismo nombre.
wiki.reserved_page=El nombre de la página wiki %s está reservado, seleccione un nombre diferente.
wiki.pages=Páginas
wiki.last_updated=Última actualización %s
@@ -701,6 +778,9 @@ activity.period.halfweekly=3 días
activity.period.weekly=1 semana
activity.period.monthly=1 mes
activity.overview=Resumen
activity.active_prs_count_1=<strong>%d</strong> Solicitud de extracción Activa
activity.active_prs_count_n=<strong>%d</strong> Solicitudes "pull" activas
activity.merged_prs_count_1=Solicitud de extracción combinada
activity.closed_issues_count_1=Incidencia cerrada
activity.closed_issues_count_n=Incidencias cerradas
activity.title.issues_n=%d incidencias
@@ -710,12 +790,14 @@ activity.closed_issue_label=Cerrada
activity.new_issues_count_1=Nueva incidencia
activity.new_issues_count_n=Nuevas incidencias
activity.new_issue_label=Abierta
activity.unresolved_conv_desc=Lista de todos los problemas antiguos y solicitudes de extracción, que han cambiado recientemente pero que aún no se han resuelto.
search=Buscar
search.search_repo=Buscar repositorio
search.results=Resultados de la búsqueda para "%s" en <a href="%s">%s</a>
settings=Configuración
settings.desc=La configuración es donde puede administrar la configuración del repositorio
settings.options=Opciones
settings.collaboration=Colaboración
settings.collaboration.admin=Administrador
@@ -727,6 +809,7 @@ settings.githooks=Git Hooks
settings.basic_settings=Configuración Básica
settings.mirror_settings=Configuración de réplica
settings.sync_mirror=Sincronizar ahora
settings.mirror_sync_in_progress=Sincronización de clone en progreso. Actualice la página en un minuto para revisar.
settings.site=Sitio oficial
settings.update_settings=Actualizar configuración
settings.advanced_settings=Ajustes avanzados
@@ -738,20 +821,27 @@ settings.external_wiki_url_desc=Los visitantes serán redireccionados a la URL c
settings.issues_desc=Habilitar rastreo de incidencias
settings.use_internal_issue_tracker=Usar rastreo de incidencias ligero incluido
settings.use_external_issue_tracker=Usar tracker externo de incidencias
settings.external_tracker_url_error=La URL del "rastreador de problemas externos" no es válida
settings.external_tracker_url_desc=Los visitantes serán redireccionados a la URL cuando hagan click en la pestaña.
settings.tracker_url_format=Formato URL del tracker de incidencias externo
settings.tracker_issue_style=Estilo de etiquetado del tracker externo de incidencias:
settings.tracker_issue_style.numeric=Numérico
settings.tracker_issue_style.alphanumeric=Alfanumérico
settings.tracker_url_format_desc=Puedes usar las plantillas <code>{user} {repo} {index}</code> para el nombre de usuario, nombre del repositorio e índice de la incidencia.
settings.enable_timetracker=Habilitar rastreador de tiempo
settings.allow_only_contributors_to_track_time=Permitir que sólo los contribuyentes registren el tiempo
settings.pulls_desc=Habilitar Pull Requests para aceptar contribuciones públicas
settings.danger_zone=Zona de Peligro
settings.new_owner_has_same_repo=El nuevo propietario tiene un repositorio con el mismo nombre.
settings.convert=Convertir en un repositorio normal
settings.convert_desc=Puede convertir este clone a un depósito regular. No se puede deshacer.
settings.convert_notices_1=- Esta operación convertirá este repositorio espejo en un repositorio normal y no podrá deshacerse.
settings.convert_confirm=Confirmar conversión
settings.convert_succeed=El repositorio se ha convertido en un repositorio regular.
settings.transfer=Transferir la propiedad
settings.transfer_desc=Transferir este repositorio a otro usuario u organización donde tengas permisos de administración.
settings.transfer_notices_1=- Perderá el acceso si el nuevo propietario es un usuario individual.
settings.transfer_notices_2=- Conservará el privilegio de acceso si el nuevo propietario es una organización y usted es uno de los propietarios de dicha organización.
settings.transfer_form_title=Por favor, introduce la siguiente información para confirmar la operación:
settings.wiki_delete=Eliminar datos de la wiki
settings.wiki_delete_desc=Una vez borrados los datos de la wiki no habrá vuelta atrás. Por favor, asegúrate de que es lo que quieres.
@@ -760,9 +850,13 @@ settings.wiki_deletion_success=Los datos de la wiki del repositorio han sido bor
settings.delete=Eliminar este repositorio
settings.delete_desc=Una vez has eliminado un repositorio, no hay vuelta atrás. Por favor, asegúrate de que es lo que quieres.
settings.delete_notices_1=- Esta operación <strong>NO PUEDE</strong> revertirse.
settings.delete_notices_2=- Esta operación borrará permanentemente todo en el repositorio de <strong>%s</strong>, incluidas asociaciones de código, problemas, comentarios, wiki y colaboradores.
settings.delete_notices_fork_1=- Todos los forks se convertirán en repositorios independientes después de la eliminación.
settings.deletion_success=Repositorio se ha eliminado.
settings.update_settings_success=Las opciones del repositorio han sido actualizadas.
settings.transfer_owner=Nuevo Propietario
settings.make_transfer=Transferir
settings.transfer_succeed=La propiedad del repositorio ha sido transferida.
settings.confirm_delete=Confirmar eliminación
settings.add_collaborator=Añadir nuevo colaborador
settings.add_collaborator_success=El nuevo colaborador ha sido añadido.
@@ -774,10 +868,13 @@ settings.search_user_placeholder=Buscar usuario...
settings.org_not_allowed_to_be_collaborator=Las organizaciones no tiene permitido ser añadidas como colaboradores.
settings.user_is_org_member=El usuario es miembro de la organización, no puede ser añadido como colaborador.
settings.add_webhook=Añadir Webhook
settings.hooks_desc=Los webhooks son muy similares a los desencadenantes básicos de eventos HTTP POST. Cuando ocurra algo en Gitea, enviaremos una notificación al host objetivo. Aprende más en el <a target="_blank" rel="noopener" href="%s">webhooks guide</a>.
settings.webhook_deletion=Eliminar Webhook
settings.webhook_deletion_desc=Eliminar este webhook eliminará su información y todo el historial de entrega. ¿Seguro que desea continuar?
settings.webhook_deletion_success=¡Webhook eliminado con éxito!
settings.webhook.test_delivery=Test de entrega
settings.webhook.test_delivery_desc=Enviar un falso evento Push de entrega para probar tus ajustes de webhook
settings.webhook.test_delivery_success=Un Webhook de prueba se ha agregado a la cola de entrega. Puede tomar algunos segundos antes de aparecer en la historia de entrega.
settings.webhook.request=Petición
settings.webhook.response=Respuesta
settings.webhook.headers=Encabezado
@@ -787,6 +884,7 @@ settings.githook_edit_desc=Si el hook no está activo, se mostrará contenido de
settings.githook_name=Nombre del Hook
settings.githook_content=Contenido del Hook
settings.update_githook=Actualizar Hook
settings.add_webhook_desc=Gitea enviará una solicitud <code>POST</code> a la URL que especifique, junto con información sobre el evento que ocurrió. También puede especificar qué formato de datos desea recibir al activar el enlace (JSON, x-www-form-urlencoded, XML, etc.). Encontrará más información en nuestra <a target="_blank" rel="noopener" href="%s">webhooks guide</a>.
settings.payload_url=URL de Payload
settings.content_type=Tipo de contenido
settings.secret=Secreto
@@ -804,6 +902,7 @@ settings.event_create_desc=Rama o etiqueta creada
settings.event_pull_request_desc=Pull request, abierta, cerrada, reabierta, editada, asignada, desasignada, con etiqueta actualizada, con etiqueta eliminada, o sincronizada.
settings.event_push_desc=Git push a un repositorio
settings.active=Activo
settings.active_helper=También se enviará información sobre el evento que activó el anclaje.
settings.add_hook_success=Se ha añadido un nuevo webhook.
settings.update_webhook=Actualizar Webhook
settings.update_hook_success=Se ha actualizado el Webhook.
@@ -814,6 +913,8 @@ settings.add_slack_hook_desc=Añade integración con <a href="%s">Slack</a> a tu
settings.slack_token=Token
settings.slack_domain=Dominio
settings.slack_channel=Canal
settings.add_discord_hook_desc=Agregue la integración con <a href="%s">Discord</a> a su repositorio.
settings.add_dingtalk_hook_desc=Añadir integración <a href="%s">Dingtalk</a> a su repositorio.
settings.deploy_keys=Claves de Despliegue
settings.add_deploy_key=Añadir Clave de Despliegue
settings.deploy_key_desc=La clave de desarrollo tiene sólo acceso de lectura. No es igual que las claves SSH de las cuentas personales.
@@ -824,6 +925,12 @@ settings.key_been_used=Se ha usado la clave de despliegue.
settings.key_name_used=Ya existe una clave de despliegue con el mismo nombre.
settings.add_key_success=¡La nueva clave de desplieque '%s' ha sido creada con éxito!
settings.deploy_key_deletion=Eliminar Clave de Despliegue
settings.deploy_key_deletion_desc=Eliminar esta clave evitará que este repositorio tenga acceso con él. ¿Desea continuar?
settings.deploy_key_deletion_success=Clave de implementación eliminada con éxito.
settings.protect_this_branch=Proteger esta rama
settings.protect_this_branch_desc=Desactiva "push" a la fuerza y evita la eliminación.
settings.protect_whitelist_committers=Lista blanca de quien puede publicar en esta rama
settings.protect_whitelist_committers_desc=Agregue usuarios o equipos a la lista blanca. Los usuarios de la lista blanca omiten restricciones de inserción típicas.
settings.protect_whitelist_search_users=Buscar usuarios
settings.protect_whitelist_teams=Equipos cuyos miembros pueden hacer push a esta rama.
settings.protect_whitelist_search_teams=Buscar equipos
@@ -858,6 +965,8 @@ release.stable=Estable
release.edit=editar
release.ahead=<strong>%d</strong> commits en %s desde esta release
release.source_code=Código Fuente
release.new_subheader=Publique lanzamientos para hacer un seguimiento a las versiones de proyecto.
release.edit_subheader=Un registro de cambios detallado puede ayudar a los usuarios a comprender qué se ha cambiado.
release.tag_name=Nombre de la etiqueta
release.target=Destino
release.tag_helper=Escoge una etiqueta existente o crea una nueva.
@@ -942,6 +1051,7 @@ settings.delete_prompt=La organización será eliminada permanentemente. ¡Y <st
settings.confirm_delete_account=Confirmar eliminación
settings.delete_org_title=Eliminación de la organización
settings.delete_org_desc=Esta organización se va a eliminar permanentemente, ¿estás seguro de querer continuar?
settings.hooks_desc=Añadir webhooks que serán ejecutados para <strong>todos los repositorios</strong> de esta organización.
members.membership_visibility=Visibilidad de Membresía:
members.public=Público
@@ -961,7 +1071,9 @@ teams.leave=Abandonar
teams.read_access=Acceso de Lectura
teams.read_access_helper=Este equipo podrá ver y clonar sus repositorios.
teams.write_access=Acceso de Escritura
teams.write_access_helper=Este grupo podrá leer e publicar a sus repositorios.
teams.admin_access=Acceso de administrador
teams.admin_access_helper=Este equipo podrá hacer push/pull en sus repositorios, así como añadir otros colaboradores a ellos.
teams.no_desc=Este equipo no tiene descripción
teams.settings=Configuración
teams.owners_permission_desc=Los propietarios tienen acceso completo a <strong>todos los repositorios</strong> y tienen <strong>derechos de administración</strong> en la organización.
@@ -970,6 +1082,7 @@ teams.update_settings=Actualizar configuración
teams.delete_team=Eliminar este equipo
teams.add_team_member=Añadir miembro al equipo
teams.delete_team_title=Eliminar equipo
teams.delete_team_desc=Ya que se eliminará este equipo, los miembros de este pueden perder acceso a algunos repositorios. ¿Desea continuar?
teams.delete_team_success=El equipo ha sido eliminado.
teams.read_permission_desc=Este equipo tiene permisos de <strong>Lectura</strong>: sus miembros pueden ver y clonar los repositorios del equipo.
teams.write_permission_desc=Este equipo tiene permisos de <strong>Escritura</strong>: sus miembros pueden leer y hacer push a los repositorios del equipo.
@@ -999,8 +1112,22 @@ dashboard.statistic_info=La base de datos de Gitea contiene <b>%d</b> usuarios,
dashboard.operation_name=Nombre de la operación
dashboard.operation_switch=Interruptor
dashboard.operation_run=Ejecutar
dashboard.clean_unbind_oauth_success=Se han eliminado las conexiones de OAuth no vinculadas.
dashboard.delete_inactivate_accounts=Eliminar todas las cuentas inactivas
dashboard.delete_inactivate_accounts_success=Todas las cuentas inactivas han sido eliminadas.
dashboard.delete_repo_archives=Eliminar todos los archivos de repositorios
dashboard.delete_repo_archives_success=Todos los archivos de repositorios han sido eliminados.
dashboard.delete_missing_repos=Eliminar todos los registros de repositorio que le faltan sus archivos Git
dashboard.delete_missing_repos_success=Se han eliminado todos los registros de repositorio que faltan los archivos de Git.
dashboard.git_gc_repos=Llevar acabo recolección de basura en todos los repositorios
dashboard.git_gc_repos_success=Todos los repositorios han terminado de ejecutar la recolección de basura.
dashboard.resync_all_sshkeys=Escriba de nuevo el archivo '.ssh/authorized_keys' (para las teclas de Gitea SSH). No es necesario hacer esto si está utilizando el servidor SSH incorporado.
dashboard.resync_all_sshkeys_success=Todas las claves públicas controladas por Gitea han sido reescritas.
dashboard.resync_all_hooks=Resincronice los anclajes de pre-recepción, actualización y post-recepción de todos los repositorios.
dashboard.resync_all_hooks_success=Se han vuelto a sincronizar todos los "hooks" de pre-recepción, actualización y post-recepción de los repositorios.
dashboard.reinit_missing_repos=Reiniciar todos los repositorios Git faltantes de los que existen registros
dashboard.reinit_missing_repos_success=Todos los repositorios Git faltantes para los que existen registros se han reinicializado.
dashboard.sync_external_users_started=Sincronización externa del usuario iniciada
dashboard.server_uptime=Tiempo de actividad del servidor
dashboard.current_goroutine=Gorutinas actuales
dashboard.current_memory_usage=Uso de memoria actual
@@ -1040,10 +1167,12 @@ users.created=Creado
users.last_login=Último inicio de sesión
users.never_login=Nunca inició sesión
users.send_register_notify=Enviar notificación de registro al usuario
users.new_success=La cuenta '%s' ha sido creada.
users.edit=Editar
users.auth_source=Fuente de Autenticación
users.auth_login_name=Nombre de Inicio de sesión de autenticación
users.password_helper=Deje el campo vacío si no desea cambiar la contraseña.
users.update_profile_success=Perfil de cuenta actualizado.
users.edit_account=Editar Cuenta
users.max_repo_creation=Límite máximo de repositorios
users.max_repo_creation_desc=(Configura a -1 para usar el límite global por defecto)
@@ -1051,10 +1180,13 @@ users.is_admin=Esta cuenta tiene permisos de administrador
users.allow_import_local=Esta cuenta dispone de permisos para importar repositorios locales
users.update_profile=Actualizar Perfil de la Cuenta
users.delete_account=Eliminar esta Cuenta
users.still_own_repo=Este usuario todavía posee uno o más repositorios. Estos repositorios que deben ser eliminados o trasladados primero.
users.still_has_org=Este usuario todavía es miembro de una o más organizaciones. Este usuario necesita abandonar o eliminarlas primero.
orgs.name=Nombre
orgs.teams=Equipos
orgs.members=Miembros
orgs.new_orga=Crear organización
repos.owner=Propietario
repos.name=Nombre
@@ -1074,6 +1206,7 @@ auths.security_protocol=Protocolo de seguridad
auths.domain=Dominio
auths.port=Puerto
auths.bind_password=Contraseña Bind
auths.bind_password_helper=Advertencia: Esta contraseña se almacena en texto sin formato. Se recomienda usar una cuenta de solo lectura.
auths.user_base=Base de búsqueda de usuarios
auths.user_dn=DN de Usuario
auths.attribute_username=Atributo de nombre de usuario
@@ -1087,13 +1220,29 @@ auths.admin_filter=Filtro de aministrador
auths.smtp_auth=Tipo de autenticación SMTP
auths.smtpport=Puerto SMTP
auths.allowed_domains=Dominios Permitidos
auths.allowed_domains_helper=Dejar vacío para permitir todos los dominios. Múltiples dominios deben estar separados por una coma ','.
auths.enable_tls=Habilitar cifrado TLS
auths.skip_tls_verify=Omitir la verificación TLS
auths.pam_service_name=Nombre del Servicio PAM
auths.oauth2_use_custom_url=Utilizar URLs personalizadas en vez de direcciones URL por defecto
auths.enable_auto_register=Hablilitar Auto-Registro
auths.tips=Consejos
auths.tips.oauth2.general.tip=Al registrar una nueva autenticación vía OAuth2, la URL de devolución/redirección debe ser: <host>/user/oauth2/<Nombre de Autenticación>/callback
auths.tip.bitbucket=Registrar un nuevo usuario de OAuth en https://bitbucket.org/account/user/<your username>/oauth-consumers/new y agregar el permiso "Cuenta"-"Lectura
auths.tip.dropbox=Crear nueva aplicación en https://www.dropbox.com/developers/apps
auths.tip.facebook=Registre una nueva aplicación en https://developers.facebook.com/apps y agregue el producto "Facebook Login
auths.tip.github=Registre una nueva aplicación OAuth en https://github.com/settings/applications/new
auths.tip.gitlab=Registrar nueva solicitud en https://gitlab.com/profile/applications
auths.tip.google_plus=Obtenga las credenciales del cliente de OAuth2 desde la consola API de Google (https://console.developers.google.com/)
auths.tip.openid_connect=Use el OpenID Connect Discovery URL (<server>/.well-known/openid-configuration) para especificar los puntos finales
auths.tip.twitter=Ir a https://dev.twitter.com/apps, crear una aplicación y asegurarse de que está activada la opción "Permitir que esta aplicación sea usada para iniciar sesión con Twitter".
auths.activated=Esta autenticación ha sido activada
auths.new_success=Se agregó la autenticación '%s'.
auths.update_success=Configuración de autenticación actualizada.
auths.delete_auth_desc=Esta fuente de autenticación se eliminará. ¿Seguro de que quiere continuar?
auths.still_in_used=Esta fuente de autenticación todavía es utilizada por uno o más usuarios, por favor eliminarlos o convertirlos primero a otra fuente de inicio de sesión.
auths.deletion_success=¡La autenticación ha sido eliminada con éxito!
auths.login_source_exist=Fuente de inicio de sesión '%s' ya existe.
config.server_config=Configuración del servidor
config.app_name=Nombre de la Aplicación
@@ -1140,6 +1289,8 @@ config.mail_notify=Notificación por Correo Electrónico
config.disable_key_size_check=Deshabilitar la comprobación de Tamaño Mínimo de Clave
config.enable_captcha=Activar Captcha
config.active_code_lives=Habilitar Vida del Código
config.default_allow_create_organization=Permiso predeterminado para crear organizaciones
config.default_allow_only_contributors_to_track_time=Permitir que sólo los contribuyentes rastreen el tiempo de forma predeterminada
config.webhook_config=Configuración de Webhooks
config.queue_length=Tamaño de Cola de Envío
@@ -1151,6 +1302,7 @@ config.mailer_disable_helo=Desactivar HELO
config.mailer_name=Nombre
config.mailer_user=Usuario
config.send_test_mail=Enviar email de prueba
config.test_mail_failed=Error al enviar correo electrónico de prueba a '%s': %v
config.test_mail_sent=El email de prueba ha sido enviado a '%s'.
config.oauth_config=Configuración OAuth
@@ -1203,6 +1355,7 @@ monitor.start=Hora de Inicio
monitor.execute_time=Tiempo de ejecución
notices.system_notice_list=Notificaciones del Sistema
notices.view_detail_header=Ver detalles de notificación
notices.actions=Acciones
notices.select_all=Sleccionar todo
notices.deselect_all=Deseleccionar todo
@@ -1212,6 +1365,7 @@ notices.delete_all=Eliminar todas las notificaciones
notices.type=Tipo
notices.type_1=Repositorio
notices.desc=Descripción
notices.delete_success=Los avisos del sistema se han eliminado.
[action]
create_repo=creó el repositorio <a href="%s">%s</a>
@@ -1227,6 +1381,8 @@ comment_issue=`comentó en la incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=`fusionado pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=transfirió el repositorio <code>%s</code> a <a href="%s">%s</a>
push_tag=hizo push del tag <a href="%s/src/%s">%[2]s</a> a <a href="%[1]s">%[3]s</a>
delete_tag=etiqueta eliminada %[2]s de <a href="%[1]s">%[3]s</a>
delete_branch=rama %[2]s eliminada, de <a href="%[1]s">%[3]s</a>
[tool]
ago=hace %s
@@ -1251,15 +1407,23 @@ raw_minutes=minutos
[dropzone]
invalid_input_type=No está permitido cargar archivos de este tipo.
file_too_big=El tamaño del archivo ({{filesize}} MB) excede el tamaño máximo de ({{maxFilesize}} MB).
remove_file=Eliminar archivo
[notification]
unread=Sin leer
read=Leídas
no_unread=No tiene ninguna notificación sin leer.
no_read=No tiene ninguna notificación de lectura.
mark_as_read=Marcar como leído
mark_as_unread=Marcar como no leído
[gpg]
error.no_committer_account=Ninguna cuenta está vinculada al correo electrónico del colaborador
error.no_gpg_keys_found=No se encontró ninguna clave conocida en la base de datos para esta firma
error.failed_retrieval_gpg_keys=Error al recuperar clave asociada a la cuenta de colaborador
[units]
error.no_unit_allowed_repo=No se puede encontrar ninguna unidad en este repositorio a la que se le permita acceder
error.unit_not_allowed=No tiene permitido visitar esta unidad de repositorio

View File

@@ -63,6 +63,7 @@ cancel=Annuler
install=Installation
title=Configuration initiale
docker_helper=Si vous exécutez Gitea grâce à Docker, merci de lire la <a target="_blank" rel="noopener" href="%s">procédure</a> attentivement avant de modifier quoi que ce soit sur cette page.
requite_db_desc=Gitea requiert MySQL, MSSQL, PostgreSQL, SQLite3 ou TiDB.
db_title=Paramètres de la base de données
db_type=Type de base de données
host=Hôte
@@ -269,6 +270,7 @@ openid_been_used=Adresse OpenID '%s' déjà utilisée.
username_password_incorrect=Nom d'utilisateur ou mot de passe incorrect.
enterred_invalid_repo_name=Veuillez vérifier que le nom saisi du dépôt soit correct.
enterred_invalid_owner_name=Veuillez vérifier que le nom du propriétaire saisi soit correct.
enterred_invalid_password=Veuillez vérifier que le mot de passe saisi soit correct.
user_not_exist=Cet utilisateur n'existe pas.
last_org_owner=L'utilisateur à exclure est le dernier membre de l'équipe propriétaire. Il doit y avoir un autre propriétaire.
cannot_add_org_to_team=Une organisation ne peut être ajoutée comme membre d'une équipe.
@@ -399,6 +401,8 @@ valid_until=Valide jusquà
valid_forever=Valide pour toujours
last_used=Dernière utilisation le
no_activity=Aucune activité récente
can_read_info=Lecture
can_write_info=Écriture
key_state_desc=Cette clé a été utilisée durant les 7 derniers jours
token_state_desc=Ce jeton a été utilisé durant les 7 derniers jours
show_openid=Afficher sur mon profil
@@ -753,7 +757,12 @@ pulls.is_checking=La recherche de conflits est toujours en cours, veuillez rafra
pulls.can_auto_merge_desc=Cette demande d'ajout peut être fusionnée automatiquement.
pulls.cannot_auto_merge_desc=Cette demande d'ajout ne peut pas être fusionnée automatiquement à cause de conflits.
pulls.cannot_auto_merge_helper=Fusionner manuellement afin de résoudre les conflits.
pulls.no_merge_desc=Cette pull request ne peut pas être fusionnée car aucune option de fusion n'est activée.
pulls.no_merge_helper=Pour fusionner cette pull request, activez au moins une option de fusion dans les paramètres du dépôt ou fusionnez la pull request manuellement.
pulls.merge_pull_request=Fusionner la demande d'ajout
pulls.rebase_merge_pull_request=Rebase et fusionner
pulls.squash_merge_pull_request=Squash et fusionner
pulls.invalid_merge_option=Vous ne pouvez pas utiliser cette option de fusion pour cette pull request
pulls.open_unmerged_pull_exists=`Vous ne pouvez effectuer une réouverture car il y a une demande d'ajout ouverte (#%d) depuis le même dépôt avec les mêmes informations de fusion et qui est en attente de fusion.`
milestones.new=Nouveau jalon
@@ -892,6 +901,10 @@ settings.tracker_url_format_desc=Vous pouvez utiliser l'espace réservé <code>{
settings.enable_timetracker=Activer le traqueur de temps
settings.allow_only_contributors_to_track_time=N'autoriser que les contributeurs à suivre le temps
settings.pulls_desc=Activer les pull requests pour accepter les contributions publiques
settings.pulls.ignore_whitespace=Ignorer les modifications des espaces lors de la vérification des conflits
settings.pulls.allow_merge_commits=Autoriser les commits de fusion
settings.pulls.allow_rebase_merge=Autoriser le rebase pour les commits de fusion
settings.pulls.allow_squash_commits=Autoriser de squash les commits avant de fusionner
settings.danger_zone=Zone de danger
settings.new_owner_has_same_repo=Le nouveau propriétaire a déjà un dépôt nommé ainsi.
settings.convert=Convertir en dépôt ordinaire
@@ -984,6 +997,8 @@ settings.add_dingtalk_hook_desc=Intégrer <a href="%s">Dingtalk</a> à votre dé
settings.deploy_keys=Clés de déploiement
settings.add_deploy_key=Ajouter une clé de déploiement
settings.deploy_key_desc=Les clés de déploiement ont un accès en lecture seule. Elles sont différentes des clés SSH personnelles.
settings.is_writable=Autoriser l'accès en écriture
settings.is_writable_info=Cette clé peut-elle être utilisée pour <strong>push</strong> vers ce dépôt ? Les clés de déploiement ont toujours un accès de pull.
settings.no_deploy_keys=Vous n'avez ajouté aucune clé de déploiement.
settings.title=Titre
settings.deploy_key_content=Contenu
@@ -1308,6 +1323,7 @@ auths.attribute_mail=Attribut de l'e-mail
auths.attributes_in_bind=Aller chercher les attributs dans le contexte de liaison DN
auths.filter=Filtre utilisateur
auths.admin_filter=Filtre administrateur
auths.ms_ad_sa=Rechercher les attributs MS AD
auths.smtp_auth=Type d'authentification SMTP
auths.smtphost=Hôte SMTP
auths.smtpport=Port SMTP

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,15 @@
app_desc=Un servizio Git auto-ospitato pronto all'uso
home=Home
dashboard=Pannello di controllo
explore=Esplora
help=Aiuto
sign_in=Accedi
sign_in_with=Accedi con
sign_out=Esci
sign_up=Registrati
link_account=Collega account
link_account_signin_or_signup=Effettua il login con le credenziali esistenti per collegare il tuo account esistente con questo; oppure crea un nuovo account
register=Registrati
website=Sito Web
version=Versione
@@ -16,6 +20,7 @@ notifications=Notifiche
create_new=Crea...
user_profile_and_more=Profilo utente e altro
signed_in_as=Accesso effettuato come
enable_javascript=Questo sito funziona meglio con JavaScript
username=Nome utente
email=E-mail
@@ -32,14 +37,21 @@ mirror=Mirror
new_repo=Nuovo Repository
new_migrate=Nuova Migrazione
new_mirror=Nuovo Mirror
new_fork=Nuovo Fork
new_org=Nuova organizzazione
manage_org=Gestisci le organizzazioni
admin_panel=Pannello di amministrazione
account_settings=Impostazioni dell'account
settings=Impostazioni
your_profile=Il tuo profilo
your_starred=Stellate
your_settings=Impostazioni
all=Tutti
sources=Sorgenti
mirrors=Mirror
collaborative=Condivisi
forks=Fork
activities=Attivitá
pull_requests=Pull Request
@@ -49,21 +61,29 @@ cancel=Annulla
[install]
install=Installazione
title=Configurazione iniziale
docker_helper=Se stai utilizzando Gitea su Docker, per favore leggi le <a target="_blank" rel="noopener" href="%s">linee guida</a> con attenzione prima di cambiare qualcosa su questa pagina.
requite_db_desc=Gitea richiede MySQL, PostgreSQL, SQLite3 o TiDB.
db_title=Impostazioni Database
db_type=Tipo di database
host=Host
user=Utente
password=Password
db_name=Nome del database
db_helper=Utilizza il motore INNODB con codifica utf8_general_ci per MySQL.
ssl_mode=Modalità SSL
path=Percorso
sqlite_helper=Il percorso assoluto al database SQLite3 o TiDB. <br>Per favore usa il percorso assoluto quando usi Gitea come servizio.
err_empty_db_path=Il percorso file del database SQLite3 o TiDB non può essere vuoto.
err_invalid_tidb_name=Il nome del database TiDB non ammette caratteri "." e "-".
no_admin_and_disable_registration=Non puoi disabilitare la registrazione senza aver creato un amministratore.
err_empty_admin_password=La password dell'amministratore non puo' essere vuota.
general_title=Impostazioni Generali
app_name=Nome Applicazione
app_name_helper=Puoi inserire qui il nome della tua organizzazione.
repo_path=Percorso Root del Repository
repo_path_helper=Tutti i repository Git remoti saranno salvati in questa directory.
lfs_path=Percorso file LFS
lfs_path_helper=I file aggiunti con Git LFS verranno salvati in questa cartella. Lascia vuoto per disabilitare LFS.
run_user=Esegui con l'utente
@@ -71,9 +91,11 @@ run_user_helper=L'utente deve avere accesso al percorso root del repository e av
domain=Dominio
domain_helper=Questo influisce sugli URL per il clonaggio via SSH.
ssh_port=Porta SSH
ssh_port_helper=Numero di porta utilizzato dal server SSH esistente. Lascia vuoto per disabilitare l'integrazione con SSH.
http_port=Porta HTTP
http_port_helper=Porta di ascolto dell'applicazione.
app_url=URL Applicazione
app_url_helper=Questo influisce sugli URL per il clonaggio tramite HTTP/HTTPS e alcune notifiche email.
log_root_path=Percorso dei log
log_root_path_helper=Directory in cui scrivere i file di log.
@@ -81,20 +103,29 @@ optional_title=Impostazioni Facoltative
email_title=Impostazioni E-mail
smtp_host=Host SMTP
smtp_from=Da
smtp_from_helper=Mail da indirizzo, RFC 5322. Può essere un singolo indirizzo email oppure il formato "Nome" <email@esempio.com>.
mailer_user=Mittente
mailer_password=Password del Mittente
register_confirm=Abilita Conferma di Registrazione
mail_notify=Abilita Notifiche Tramite Email
server_service_title=Impostazioni del Server e Altri Servizi
offline_mode=Abilita Modalità Offline
offline_mode_popup=Disabilitare CDN in modo che tutti i file di risorse siano serviti localmente.
disable_gravatar=Disattiva il servizio Gravatar
disable_gravatar_popup=Disabilita Gravatar e sorgenti customizzate, tutti gli avatar vengono caricati dagli utenti o come predefinito.
federated_avatar_lookup=Abilita Ricerca di Federated Avatar
federated_avatar_lookup_popup=Enable federated avatars lookup to use federated open source service based on libravatar.
disable_registration=Disabilita Registrazione Manuale
disable_registration_popup=Disabilita la registrazione manuale degli utenti, solo gli amministratori possono creare account.
openid_signin=Attiva l'accesso OpenID
openid_signin_popup=Abilitare il login utente tramite OpenID
openid_signup=Abilitare la registrazione automatica OpenID
openid_signup_popup=Abilita la registrazione automatica basata su OpenID
enable_captcha=Abilita Captcha
enable_captcha_popup=Richiedi convalida captcha per i nuovi utenti.
require_sign_in_view=Abilita Richiesta di Accesso per Vedere le Pagine
require_sign_in_view_popup=Solo gli utenti loggati possono vedere le pagine, i visitatori potranno vedere solo le pagine di accesso e registrazione.
admin_setting_desc=Non è necessario creare un account admin in questo momento. Il primo utente che si registra sul sito guadagnerà automaticamente l'accesso a livello amministratore.
admin_title=Impostazioni Account Amministratore
admin_name=Nome utente
admin_password=Password
@@ -102,44 +133,92 @@ confirm_password=Conferma Password
admin_email=E-mail dell'Admin
install_btn_confirm=Installare Gitea
test_git_failed=Fallito il test del comando git: %v
sqlite3_not_available=La tua attuale versione non supporta SQLite3, si prega di scaricare la versione eseguibile ufficiale da %s, NON la versione gobuild.
invalid_db_setting=Configurazione del database non valida: %v
invalid_repo_path=Percorso root del repository invalido: %v
run_user_not_match=Esegui utente non è l'utente corrente: %s -> %s
save_config_failed=Salvataggio della configurazione non riuscito: %v
invalid_admin_setting=Impostazioni account Admin non valide: %v
install_success=Benvenuto! Grazie per aver scelto Gitea. Divertiti e abbi cura di te!
invalid_log_root_path=Percorso dei log invalido: %v
default_keep_email_private=Valore predefinito per mantenere Privata Email
default_keep_email_private_popup=Questo è il valore di default per la visibilità dell'indirizzo email dell'utente. Se impostato a vero l'indirizzo email di tutti i nuovi utenti sarà nascosto fino a quando l'utente non cambierà le sue impostazioni.
default_allow_create_organization=Valore di autorizzazione predefinito per i nuovi utenti per creare organizzazioni
default_allow_create_organization_popup=Questo è il valore di default del permesso che sarà assegnato ad ogni nuovo utente. Se impostato su vero ai nuovi utenti sarà permesso creare Organizzazioni.
default_enable_timetracking_popup=I repository avranno il monitoraggio del tempo abilitato per impostazione predefinita in base a queta configurazione
no_reply_address=Indirizzo di non riposta
no_reply_address_helper=Dominio per indirizzo di posta elettronica dell'utente nei registri di git se egli mantiene il suo indirizzo email privato. Ad esempio, l'utente 'joe' e 'noreply.example.org' sarà 'joe@noreply.example.org'
[home]
uname_holder=Nome Utente o E-mail
password_holder=Password
switch_dashboard_context=Cambia Dashboard Context
my_repos=I miei Repository
show_more_repos=Mostra altri repository...
collaborative_repos=Repository Condivisi
my_orgs=Le mie Organizzazioni
my_mirrors=I miei Mirror
view_home=Vedi %s
search_repos=Trova un repository ...
issues.in_your_repos=Nei tuoi repository
[explore]
repos=Repository
users=Utenti
organizations=Organizzazioni
search=Cerca
repo_no_results=Non sono stati trovati repository corrispondenti.
user_no_results=Non sono stati trovati utenti corrispondenti.
org_no_results=Non sono state trovate organizzazioni corrispondenti.
[auth]
create_new_account=Crea Account
register_helper_msg=Hai già un account? Accedi ora!
social_register_helper_msg=Hai già una conta? Iscriviti ora!
disable_register_prompt=Siamo spiacenti, registrazione è stata disabilitata. Si prega di contattare l'amministratore del sito.
disable_register_mail=Siamo spiacenti, la conferma di registrazione via Mail è stata disattivata.
remember_me=Ricordami
forgot_password_title=Password Dimenticata
forgot_password=Password dimenticata?
sign_up_now=Bisogno di un account? Iscriviti ora.
confirmation_mail_sent_prompt=Una nuova email di conferma è stata inviata a <b>%s</b>. Per favore controlla la tua posta in arrivo nelle prossime %s per completare il processo di registrazione.
reset_password_mail_sent_prompt=Una email di conferma è stata inviata a <b>%s</b>. Per favore controlla la tua posta in arrivo nelle prossime %s per completare il processo di reset della password.
active_your_account=Attiva il tuo Account
prohibit_login=Accesso Vietato
prohibit_login_desc=Il tuo account è impossibilitato al login, contatta l'amministratore del sito.
resent_limit_prompt=Siamo spiacenti, hai già richiesto un'e-mail di attivazione recentemente. Si prega di attendere 3 minuti, quindi riprovare.
has_unconfirmed_mail=Ciao %s, hai un indirizzo di posta elettronica non confermato (<b>%s</b>). Se non hai ricevuto una e-mail di conferma o vuoi riceverla nuovamente, fare clic sul pulsante qui sotto.
resend_mail=Clicca qui per inviare nuovamente l'e-mail di attivazione
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
reset_password=Reimposta la tua Password
invalid_code=Siamo spiacenti, il tuo codice di conferma è scaduto o non è valido.
reset_password_helper=Clicca qui per reimpostare la password
password_too_short=La lunghezza della password non può essere meno %d caratteri.
non_local_account=La conta non locali non possono cambiare la password attraverso l'interfaccia web di Gitea.
verify=Verifica
scratch_code=Codice Gratta e Vinci
use_scratch_code=Utilizza un codice di zero
twofa_scratch_used=Hai usato il tuo codice zero. Sei stato reindirizzato alla pagina di configurazione a due fattori quindi puoi rimuovere la registrazione dal dispositivo o generare un nuovo codice zero.
twofa_passcode_incorrect=Il codice di accesso non è corretto. Se smarrito il tuo dispositivo, utilizzare il codice gratta e Vinci per effettuare il login.
twofa_scratch_token_incorrect=I tuo codice scratch non è corretto.
login_userpass=Utente / Password
login_openid=OpenID
openid_connect_submit=Connetti
openid_connect_title=Connetti a una conta esistente
openid_connect_desc=Il sistema non conosce gli URI OpenID scelti, è possibile aggiungerlo a una conta esistente.
openid_register_title=Crea Nuovo Account
openid_register_desc=Il sistema non conosce gli URI OpenID scelti, è possibile associarli a una nuova conta.
openid_signin_desc=Esempio di URIs: https://anne.me, bob.openid.org.cn, gnusocial.net/carry
disable_forgot_password_mail=Siamo spiacenti, la reimpostazione della password è stata disabilitata. Si prega di contattare l'amministratore del sito.
[mail]
activate_account=Per favore attiva il tuo account
activate_email=Verifica il tuo indirizzo e-mail
reset_password=Reimposta la tua password
register_success=Registrazione completata con successo
register_notify=Benvenuto su Gitea
[modal]
yes=
@@ -167,6 +246,9 @@ TreeName=Percorso del file
Content=Contenuto
require_error=` non può essere vuoto.`
alpha_dash_error=` ammessi solo caratteri alfanumerici o trattini(-_).`
alpha_dash_dot_error=` ammessi solo caratteri alfanumerici, trattini(-_) o punti.`
git_ref_name_error=`deve essere ben formato come nome di riferimento.`
size_error='deve essere %s.'
min_size_error=` deve contenere almeno %s caratteri.`
max_size_error=` deve contenere massimo %s caratteri.`
@@ -174,10 +256,32 @@ email_error=` non è un indirizzo e-mail valido.`
url_error=` non è un URL valido.`
include_error=` deve contenere la stringa '%s'.`
unknown_error=Errore sconosciuto:
captcha_incorrect=Il Captcha non corrisponde.
password_not_match=Le password inserite non corrispondono.
username_been_taken=Nome utente già in uso.
repo_name_been_taken=Nome del repository già in uso.
org_name_been_taken=Nome dell'organizzazione già in uso.
team_name_been_taken=Il nome del Team è già utilizzato.
team_no_units_error=La squadra deve avere almeno un'unità abilitata.
email_been_used=Email già in uso.
openid_been_used=Indirizzo OpenID '%s' già utilizzato.
username_password_incorrect=Nome utente o password errati.
enterred_invalid_repo_name=Si prega di assicurarsi che il nome del repository inserito sia corretto.
enterred_invalid_owner_name=Si prega di assicurarsi che il nome del proprietario inserito sia corretto.
enterred_invalid_password=Assicurati che la password che hai inserito sia corretta.
user_not_exist=L'utente non esiste.
last_org_owner=La rimozione dell'ultimo utente rimasto dai proprietari del team non è permesso perché deve esserci sempre almeno un proprietario in ogni organizzazione.
cannot_add_org_to_team=L'Organizzazione non può essere aggiunta come membro del team.
invalid_ssh_key=Siamo spiacenti, non siamo stati in grado di verificare la tua chiave SSH: %s
invalid_gpg_key=Siamo spiacenti, non siamo stati in grado di verificare la tua chiave GPG: %s
unable_verify_ssh_key=La chiave ssh non può essere verificata; per favore controlla di nuovo se c'è un errore.
auth_failed=Autenticazione non riuscita: %v
still_own_repo=Il tuo account possiede ancora almeno un repository, dovete prima cancellarli o trasferirne la proprietà.
still_has_org=La tua conta è ancora membro di almeno un'organizzazione; devi lasciarli prima.
org_still_own_repo=Questa organizzazione ha ancora repository; è necessario eliminarli o tranferirli prima.
target_branch_not_exist=Il ramo (branch) di destinazione non esiste.
@@ -192,63 +296,98 @@ following=Seguiti
follow=Segui
unfollow=Non seguire più
form.name_reserved=L'username '%s' è riservato.
form.name_pattern_not_allowed=La struttura del nome utente '%s' non è consentita.
[settings]
profile=Profilo
password=Password
security=Sicurezza
avatar=Avatar
ssh_gpg_keys=SSH / GPG chiavi
social=Account Sociali
applications=Applicazioni
orgs=Organizzazioni
repos=Repository
delete=Elimina account
twofa=Verifica in due passaggi
account_link=Conta esterni
organization=Organizzazione
uid=Uid
public_profile=Profilo pubblico
profile_desc=Il tuo indirizzo email è pubblico e verrà utilizzato per le notifiche relative conta e alle operazioni basate sul web tramite l'interfaccia web.
password_username_disabled=Gli utenti non locali non sono ammessi a cambiare il loro nome utente. Per maggiori dettagli si prega di contattare l'amministratore di sistema.
full_name=Nome Completo
website=Sito web
location=Posizione
update_profile=Aggiorna Profilo
update_profile_success=Il tuo profilo è stato aggiornato.
change_username=Username Cambiato
change_username_prompt=Questa modifica cambierà i collegamenti a la tua conta.
continue=Continua
cancel=Annulla
lookup_avatar_by_mail=Ricerca Avatar per mail
federated_avatar_lookup=Ricerca per avatar federata
enable_custom_avatar=Abilita avatar personalizzato
choose_new_avatar=Scegli un nuovo avatar
update_avatar=Aggiorna le impostazioni avatar
delete_current_avatar=Elimina Avatar attuale
uploaded_avatar_not_a_image=Il file caricato non è un'immagine.
update_avatar_success=Le impostazioni del tuo avatar sono state aggiornate.
change_password=Cambia Password
old_password=Password attuale
new_password=Nuova Password
retype_new_password=Re-inserisci la password
password_incorrect=La Password attuale non è corretta.
change_password_success=La tua password è stata cambiata con successo. Ora puoi firmare usando la tua nuova password.
password_change_disabled=Gli utenti non locali non possono cambiare la loro password attraverso l'interfaccia web.
emails=Indirizzi e-mail
manage_emails=Gestisci indirizzi email
manage_openid=Gestici gli indirizzi OpenID
email_desc=Il tuo indirizzo e-mail primario sarà usato per le notifiche e altre operazioni.
primary=Primario
primary_email=Imposta come primario
delete_email=Elimina
email_deletion=Elimina E-mail
email_deletion_desc=Eliminado questo indirizzo email tutte le informazioni correlate nel tuo conta verranno eliminate. Git conferma che l'uso di questa email non cambierà. Vuoi continuare?
email_deletion_success=Indirizzo e-mail eliminato con successo!
openid_deletion=Eliminazione OpenID
openid_deletion_desc=La rimozione di questo indirizzo OpenID della tua conta ti impedirà di accedere con esso. Sei sicuro di voler continuare?
openid_deletion_success=OpenID è stato rimosso con successo!
add_new_email=Aggiungi un nuovo indirizzo E-mail
add_new_openid=Aggiungere nuovo OpenID URI
add_email=Aggiungi E-mail
add_openid=Aggiungere OpenID URI
add_email_confirmation_sent=Una nuova email di conferma è stata inviata a '%s'. Si prega di controllare la tua casella di posta entro il prossimo %s per confermare la tua email.
add_email_success=Il tuo nuovo indirizzo e-mail è stato aggiunto con successo.
add_openid_success=Il tuo nuovo indirizzo OpenID è stato aggiunto con successo.
keep_email_private=Mantieni Indirizzo Email Privato
keep_email_private_popup=Il tuo indirizzo email sarà nascosto agli altri utenti se questa opzione è abilitata.
openid_desc=Gli indirizzi OpenID ti permetteranno di delegare l'autenticazione al tuo fornitore di scelta
manage_ssh_keys=Gestisci chiavi SSH
add_key=Aggiungi Chiave
ssh_desc=Queste sono le chiavi SSH associate a la tua conta. Perchè queste chiavi consentono a chiunque le usi di accedere ai propri repository, è molto importante assicurarsi di riconoscerle.
gpg_desc=Queste sono le chiavi GPG associate a la tua conta. Perchè queste chiavi consentono di confermare, è molto importante mantenere la chiave privata corrispondente al sicuro.
ssh_helper=<strong> Hai bisogno di aiuto?</strong> Dai un'occhiata alla guida di GitHub <a href="%s">crea le tue chiavi SSH </a> o risolvere <a href="%s"> problemi comuni </a> puoi trovare usando SSH.
add_new_key=Aggiungi Chiave SSH
key_name=Nome della Chiave
key_content=Contenuto
delete_key=Elimina
ssh_key_deletion=Eliminazione chiave SSH
ssh_key_deletion_desc=Rimuovendo questa chiave SSH tutti gli accessi saranno revocati usando questa chiave SSH per la tua conta. Vuoi continuare?
add_on=Aggiunto il
last_used=Ultimo accesso il
no_activity=Nessuna attività recente
can_read_info=Letto
can_write_info=Scrivere
manage_social=Gestisci gli Account Sociali Associati
social_desc=Questa è una lista di conta social associati. Per motivi di sicurrezza, assicurati di riconoscere tutte queste voci, in quanto possono essere utilizzate per accedere a la tua conta.
unbind=Disassocia
manage_access_token=Gestisci i Token di Accesso Personale
@@ -256,9 +395,13 @@ generate_new_token=Genera Nuovo Token
new_token_desc=Da questo momento, ogni token avrà pieno accesso al tuo account.
token_name=Nome Token
generate_token=Genera Token
generate_token_success=Il token di accesso è stato generato correttamente! Assicurati di copiarlo ora, perchè non sarai più in grado di vederlo più tardi!
delete_token=Elimina
access_token_deletion=Eliminazione Token di accesso personale
access_token_deletion_desc=La rimozione di questo token di accesso personale revoca l'accesso per qualsiasi applicazioni che utilizza questo token. Vuoi continuare?
delete_token_success=Il token di accesso personale è stato rimosso. Non dimenticare di aggiornare le applicazioni che utilizzano questo token.
twofa_desc=Gitea supporta l'autenticazione a due fattori per migliorare la sicurezza de la tua conta.
twofa_disable=Disattiva verifica in due passaggi
@@ -287,11 +430,15 @@ auto_init=Inizializzare questo repository con i file e il modello selezionati
create_repo=Crea Repository
default_branch=Ramo (Branch) predefinito
mirror_prune=Rimuovi
mirror_prune_desc=Rimuovere eventuali riferimenti di tracciamento remoto che non esistono più sul telecomando
mirror_address=Indirizzo del mirror
mirror_address_desc=Si prega di includere tutte le credenziali dell'utente necessarie nell'indirizzo.
watchers=Osservatori
stargazers=Fan
forks=Fork
reactions_more=e %d più
form.reach_limit_of_creation=Hai già raggiunto il tuo limite %d repository.
need_auth=Richiesta di autorizzazione
migrate_type=Tipo di migrazione
@@ -302,6 +449,7 @@ migrate.clone_address_desc=Può essere un URL HTTP/HTTPS/GIT o il percorso del s
migrate.permission_denied=Non è consentito importare repository locali.
migrate.invalid_local_path=Percorso locale non valido, non esiste o non è una cartella.
migrate.failed=Migrazione non riuscita: %v
migrate.lfs_mirror_unsupported=La duplicazione di oggetti LFS non è supportata - usa ' git lfs fetch --tutti e 'git lfs push --tutti invece.
mirror_from=mirror da
forked_from=forkato da
@@ -340,6 +488,32 @@ editor.upload_file=Carica File
editor.edit_file=Modifica file
editor.preview_changes=Anteprima modifiche
editor.edit_this_file=Modifica questo file
editor.fork_before_edit=È necessario posizionare questo repository prima di modificare il file
editor.filename_help=Per aggiungere una directory, digitarla e premere/. Per eliminare un directory, vai all'inizio del campo e premi il tasto backspace.
editor.or=o
editor.cancel_lower=cancellare
editor.commit_changes=Apporta le modifiche
editor.add_tmpl=Aggiungi '%s/<filename>'
editor.add=Aggiungi '%s'
editor.update=Aggiornare '%s'
editor.delete=Eliminare '%s'
editor.commit_message_desc=Aggiungi una descrizione estesa facoltativa...
editor.commit_directly_to_this_branch=Impegnarsi direttamente con il <strong class="branch-name">%s</strong> branch.
editor.create_new_branch=Creare un <strong> nuovo branch</strong> per questo commit e inizia una pull request.
editor.new_branch_name_desc=Nome del nuovo branch...
editor.cancel=Cancellare
editor.filename_cannot_be_empty=Il nome del file non può essere vuoto.
editor.branch_already_exists=Branch '%s' esiste già in questo repository.
editor.directory_is_a_file=Ingresso '%s' nel percorso principale è un file non una directory in questo repository.
editor.file_is_a_symlink=Il file '%s' è un collegamento simbolico che non può essere modificato dall'editor web
editor.filename_is_a_directory=Il nome del file '%s' è un directory esistente in questo repository.
editor.file_editing_no_longer_exists=Il file '%s' staii modificando non esiste più nel repository.
editor.file_changed_while_editing=Il contenuto del file è stato modificato da quando ha iniziato la modifica.<a target="_blank" rel="noopener" href="%s"> Clicca qui</a> per vedere cosa è stato cambiato o <strong> premere di nuovo conferma</strong> per sovrascrivere tali modifiche.
editor.file_already_exists=Un file con nome '%s' esiste già in questo repository.
editor.no_changes_to_show=Non ci sono cambiamenti da mostrare.
editor.fail_to_update_file=Errore durante l'aggiornamento/ creazione del file '%s' con errore: %v
editor.add_subdir=Aggiungi sottocartella...
editor.unable_to_upload_files=Impossibile caricare i file su '%s' con errore:%v
commits.search=Ricerca una versione
commits.author=Autore
@@ -385,6 +559,13 @@ issues.filter_sort.recentupdate=Aggiornati di recente
issues.filter_sort.leastupdate=Aggiornati tempo fa
issues.filter_sort.mostcomment=I più commentati
issues.filter_sort.leastcomment=I meno commentati
issues.action_open=Aperto
issues.action_close=Chiuso
issues.action_label=Etichetta
issues.action_milestone=Pietra Miliare
issues.action_milestone_no_select=Nessuna pietra miliare
issues.action_assignee=Assegnatario
issues.action_assignee_no_select=Nessun assegnatario
issues.opened_by=aperto %[1]s da <a href="/%[2]s">%[3]s</a>
issues.opened_by_fake=aperto %[1]s da %[2]s
issues.previous=Pagina precedente
@@ -430,12 +611,21 @@ pulls.merged_title_desc=ha unito %[1]d commit da <code>%[2]s</code> a <code>%[3]
pulls.tab_conversation=Conversazione
pulls.tab_commits=Commit
pulls.tab_files=File modificati
pulls.reopen_to_merge=Riapri questa pull request per effettuare l'unione.
pulls.merged=Unito
pulls.has_merged=Questa pull request è stata unita con successo.
pulls.data_broken=I dati di questa pull request si sono rotti causa dell'eliminazione delle informazioni di fork.
pulls.is_checking=Il controllo dei conflitti è ancora in corso, per favore aggiorna pagina tra qualche istante.
pulls.can_auto_merge_desc=La pull request non può essere mergiata automaticamente.
pulls.cannot_auto_merge_desc=Questa pull request non può essere unita automaticamente poiché sono presenti dei conflitti.
pulls.cannot_auto_merge_helper=Effettua il merge manualmente per risolvere i conflitti.
pulls.no_merge_desc=Questa pull request non può essere unita poiché la possibilità di unire PR è stata disabilitata.
pulls.no_merge_helper=Per unire questa pull request abilita almeno una opzione di unione nelle impostazioni della repository o uniscila manualmente.
pulls.merge_pull_request=Unisci Pull Request
pulls.rebase_merge_pull_request=Fai rebase e unisci
pulls.squash_merge_pull_request=Fai squash e unisci
pulls.invalid_merge_option=Non puoi utilizzare questa opzione di merge per questa pull request
pulls.open_unmerged_pull_exists=`Non puoi riaprire la pull request perché c'è già una pull request aperta (#%d) nella stessa repository con le stesse informazioni per l'unione e deve ancora essere unita.`
milestones.new=Nuova Milestone
milestones.open_tab=%d Aperti
@@ -473,6 +663,10 @@ wiki.page_already_exists=Esiste già una pagina Wiki con questo stesso nome.
wiki.pages=Pagine
wiki.last_updated=Ultimo aggiornamento: %s
activity.merged_prs_count_1=Pull Request Unita
activity.merged_prs_count_n=Pull request unite
activity.title.prs_merged_by=%s unita da %s
activity.merged_prs_label=Unite
settings=Impostazioni
@@ -489,6 +683,8 @@ settings.use_internal_issue_tracker=Use builtin lightweight issue tracker
settings.use_external_issue_tracker=Utilizza gestore di problemi esterno
settings.tracker_url_format=Formato URL Gestore Problemi Esterno
settings.pulls_desc=Abilita le pull requests per accettare contributi pubblici
settings.pulls.allow_merge_commits=Permetti commit di unione
settings.pulls.allow_rebase_merge=Permetti rebase per unire commit
settings.danger_zone=Zona Pericolosa
settings.new_owner_has_same_repo=Il nuovo proprietario ha già un repository con lo stesso nome. Per favore scegli un altro nome.
settings.convert=Converti in Repository Regolare
@@ -800,6 +996,8 @@ config.db_path_helper=(per "sqlite3" e "tidb")
config.service_config=Configurazione Servizio
config.register_email_confirm=Richiedono Conferma dell'Email
config.disable_register=Disabilita Registrazione
config.enable_openid_signup=Attiva la registrazione tramite OpenID
config.enable_openid_signin=Attiva l'accesso tramite OpenID
config.show_registration_button=Mostra Pulsane Registrazione
config.require_sign_in_view=Richiesto Accesso per Vedere
config.mail_notify=Email di Notifica
@@ -815,6 +1013,7 @@ config.mailer_config=Configurazione Mailer
config.mailer_enabled=Attivo
config.mailer_disable_helo=Disattiva HELO
config.mailer_name=Nome
config.mailer_host=Host
config.mailer_user=Utente
config.send_test_mail=Invia email di test
config.test_mail_sent=Una mail di prova è stata inviata a '%s'.
@@ -841,6 +1040,12 @@ config.picture_config=Configurazione Foto
config.picture_service=Servizio foto
config.disable_gravatar=Disabilita Gravatar
config.git_max_diff_lines=Numero massimo di righe di diff (per singolo file)
config.git_max_diff_line_characters=Numero massimo di caratteri di diff (per singola riga)
config.git_max_diff_files=Numero massimo di file diff mostrati
config.git_gc_args=Parametri GC
config.git_migrate_timeout=Timeout per la migrazione
config.git_mirror_timeout=Timeout per l'aggiornamento del mirror
config.log_config=Configurazione Log
config.log_mode=Modalità Log
@@ -871,15 +1076,24 @@ create_repo=ha creato il repository <a href="%s">%s</a>
rename_repo=repository rinominato da <code>%[1]s</code> a <a href="%[2]s">[3]s</a>
commit_repo=ha pushato nel <a href="%[1]s/src/%[2]s">%[3]s</a> in <a href="%[1]s">%[4]s</a>
create_issue=`ha aperto il problema <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`problema chiuso <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`problema riaperto <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`creata pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`richiesta di pull chiuso <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`richiesta di riapertura riaperta <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`ha commentato il problema <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=`unita pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=ha trasferito il repository <code>%s</code> a <a href="%s">%s</a>
push_tag=ha pushato il tag <a href="%s/src/%s">%[2]s</a> a <a href="%[1]s">%[3]s</a>
delete_tag=tag eliminato %[2]s da <a href="%[1]s">%[3]s</a>
delete_branch=branch eliminato %[2]s da <a href="%[1]s">%[3]s</a>
compare_commits=Confronta %d commits
[tool]
ago=%s fa
from_now=%s da adesso
now=ora
future=futuro
1s=1 secondo
1m=1 minuto
1h=1 ora
@@ -898,12 +1112,23 @@ raw_seconds=secondi
raw_minutes=minuti
[dropzone]
default_message=Trascina i files o clicca per caricare.
invalid_input_type=Non è possibile caricare file di questo tipo.
file_too_big=La dimensione del file ({{filesize}} MB) supera la dimensione massima ({{maxFilesize}} MB).
remove_file=Rimuovi file
[notification]
notifications=Notifiche
no_unread=Non hai notifiche non lette.
no_read=Non hai nessuna notifica di lettura.
mark_as_read=Segna come letto
mark_as_unread=Segna come non letto
mark_all_as_read=Segna tutti come letti
[gpg]
error.no_gpg_keys_found=Non sono state trovate chiavi note per questa firma nel database
error.failed_retrieval_gpg_keys=Impossibile recuperare alcuna chiave associata a la conta del committer
[units]
error.no_unit_allowed_repo=Nessuna unità può essere trovata in questo ripository a cui è consentito l'accesso

File diff suppressed because it is too large Load Diff

View File

@@ -41,8 +41,14 @@ admin_panel=관리자 패널
account_settings=계정 설정
settings=설정
your_profile=프로필
your_starred=즐겨찾기
your_settings=설정
all=전체
sources=소스
mirrors=미러
collaborative=협업
forks=포크
activities=활동
pull_requests=풀 리퀘스트
@@ -53,6 +59,7 @@ cancel=취소
[install]
install=설치
title=초기 설정
docker_helper=Docker내에서 Gitea를 실행하고 있다면 이 페이지를 변경하기 전 <a target="_blank" href="%s">가이드라인</a>을 주의 깊게 읽어주세요.
db_title=데이터베이스 설정
db_type=데이터베이스 유형
host=호스트
@@ -80,6 +87,7 @@ run_user_helper=사용자 계정은 저장소에 접근할 권한과 Gitea를
domain=도메인
domain_helper=Git SSH url에 영향을 미칩니다.
ssh_port=SSH 포트
ssh_port_helper=SSH 서버가 실행되고 있는 포트를 입력하세요. 비워둘 경우 SSH를 사용하지 않습니다.
http_port=HTTP 포트
http_port_helper=포트 번호는 애플리케이션에서 열고 있습니다.
app_url=애플리케이션 URL
@@ -92,6 +100,7 @@ email_title=이메일 서비스 설정
smtp_host=SMTP 호스트
smtp_from=에서
smtp_from_helper=메일 발송 주소(RFC 5322). 일반적인 이메일 주소형태나 "Name" <email@example.com> 형태를 입력할 수 있습니다.
mailer_user=전송자
mailer_password=발송 주소의 비밀번호
register_confirm=등록 확인 활성화
mail_notify=메일 알림 활성화
@@ -104,6 +113,10 @@ federated_avatar_lookup=연합 아바타 조회 활성화
federated_avatar_lookup_popup=libravatar 기반 오픈소스 서비스 사용 목적으로 연합 아바타 조회를 허용하기
disable_registration=직접 등록할 수 없게 함
disable_registration_popup=사용자가 직접 등록할 수 없게 합니다. 관리자만이 추가할 수 있습니다.
openid_signin=OpenID 로그인 사용
openid_signin_popup=OpenID를 통한 유저 로그인 사용
openid_signup=OpenID 계정생성 사용
openid_signup_popup=OpenID 기반의 계정생성 사용
enable_captcha=Captcha 활성화
enable_captcha_popup=사용자 등록시 캡차 요구
require_sign_in_view=페이지를 보기 위해 로그인 사용 활성화
@@ -122,10 +135,14 @@ invalid_repo_path=저장소 루트 경로가 올바르지 않습니다: %v
run_user_not_match=실행 유저가 현재 유저가 아닙니다: %s -> %s
save_config_failed=설정을 저장할 수 없습니다: %v
invalid_admin_setting=관리자 계정 설정이 잘못되었습니다: %v
install_success=환영합니다! Gitea를 선택해 주셔서 감사합니다.
invalid_log_root_path=로그 루트 경로가 올바르지 않습니다: %v
default_keep_email_private=이메일을 숨기는 것을 기본으로 함
default_keep_email_private_popup=이것은 사용자의 이메일 주소 표시에 대한 기본 값입니다. 만약 true로 설정하신다면 모든 새로운 사용자의 이메일 주소는 그 사용자가 설정을 변경할때 까지 가려집니다.
default_allow_create_organization=새로운 사용자가 조직을 만드는것에 대한 기본 권한값
default_allow_create_organization_popup=새 사용자에게 할당될 기본 사용 권한 값입니다. 만약 true로 설정된 경우에는 새 사용자가 조직을 생성할 수 있습니다.
default_enable_timetracking=시간 추적 사용을 기본으로 함
default_enable_timetracking_popup=이 값에 따라 레포지터리의 시간대별 변경사항 추적에 대한 기본값이 설정됩니다.
no_reply_address=회신 금지 주소
[home]
@@ -183,7 +200,10 @@ login_userpass=사용자 / 비밀번호
login_openid=OpenID
openid_connect_submit=연결
openid_connect_title=기존 계정으로 연결하기
openid_connect_desc=선택한 OpenID URI는 시스템에 저장되어 있지 않습니다, 이 URI를 기존 계정에 연결시킬 수 있습니다.
openid_register_title=새 계정 생성
openid_register_desc=선택한 OpenID URI는 시스템에 저장되어 있지 않습니다, 이 URI를 새 계정과 연결시킬 수 있습니다.
openid_signin_desc=URI 예제: https://anne.me, bob.openid.org.cn, gnusocial.net/carry
disable_forgot_password_mail=죄송합니다, 비밀번호 초기화가 비활성화 되어있습니다. 사이트 관리자에게 문의 해주세요.
[mail]
@@ -221,6 +241,7 @@ Content=컨텐츠
require_error=` 비어 있을 수 없습니다.`
alpha_dash_error=`은(는) 숫자, 알파벳, 대시(-_) 문자로만 구성되어야 합니다.`
alpha_dash_dot_error=` 숫자, 알파벳, 점(.), 대시(-_) 문자로만 구성되어야 합니다.`
git_ref_name_error=` 유효한 git 레퍼런스명이어야 합니다.`
size_error=` %s 글자여야 합니다.`
min_size_error=` 최소 %s 글자여야 합니다.`
max_size_error=` %s 글자를 넘을 수 없습니다.`
@@ -228,6 +249,7 @@ email_error=` 올바른 이메일 주소가 아닙니다.`
url_error=` 올바른 URL이 아닙니다.`
include_error=` 반드시 '%s'를 포함해야 합니다.`
unknown_error=알 수 없는 오류:
captcha_incorrect=CAPTCHA에 대한 답변이 올바르지 않습니다.
username_been_taken=이미 사용하고 있는 아이디입니다.
repo_name_been_taken=이미 사용하고 있는 저장소 이름입니다.
@@ -350,6 +372,7 @@ no_activity=최근 활동 없음
key_state_desc=이 키는 최근 1주일 동안 사용된 적이 있습니다.
token_state_desc=이 토큰은 최근 1주일 동안 사용된 적이 있습니다.
show_openid=프로필에 표시
hide_openid=프로필에서 숨기기
manage_social=SNS계정 관리
unbind=해제
@@ -369,9 +392,13 @@ passcode_invalid=그 인증코드는 올바르지 않습니다. 다시 시도해
manage_account_links=계정 링크 관리
manage_account_links_desc=외부 계정들이 이 계정에 연결됨
account_links_not_available=이 계정에 연결된 외부 계정이 존재하지 않습니다.
remove_account_link=연결된 계정 삭제
remove_account_link_desc=이 연결 계정을 지우면 관련된 모든 접근 권한이 사라집니다. 계속 하시겠습니까?
remove_account_link_success=연결된 계정이 성공적으로 지워졌습니다.
orgs_none=당신은 어떤 조직의 구성원도 아닙니다.
repos_none=어떤 레포지터리도 존재하지 않습니다.
delete_account=계정 삭제
delete_prompt=당신의 계정을 삭제합니다. 완료된 후에는 <strong>취소할 수 없습니다</strong>.
@@ -385,6 +412,7 @@ repo_name=저장소 이름
repo_name_helper=좋은 저장소 이름은 보통 짧고 기억하기 좋은 특별한 키워드로 이루어 집니다.
visibility=가시성
visiblity_helper=이 저장소는 <span class="ui red text">비공개</span> 저장소입니다
visiblity_helper_forced=시스템 관리자가 모든 새 레포지터리를 <span class="ui red text">비공개</span>로 하도록 설정했습니다.
visiblity_fork_helper=(이 값의 변경은 모든 포크에 영향을 줍니다)
clone_helper=클론하는데에 도움이 필요하면 <a target="_blank" href="%s">Help</a>에 방문하세요.
fork_repo=저장소 포크
@@ -411,6 +439,7 @@ watchers=주시하고 있는 사람들
stargazers=별을 준 사람들
forks=포크
form.reach_limit_of_creation=이미 최대치인 %d 개의 레포지터리를 가지고 있습니다.
form.name_reserved=저장소 이름 '%s'은 예약 되어 있습니다.
form.name_pattern_not_allowed=저장소 이름 패턴 '%s'은 허용 되지 않습니다.
@@ -424,20 +453,31 @@ migrate.clone_local_path=또는 로컬 서버 경로
migrate.permission_denied=로컬 저장소는 가져오기를 할 수 없습니다.
migrate.invalid_local_path=잘못된 로컬 경로입니다. 존재하지 않는 경로거나 폴더가 아닙니다.
migrate.failed=마이그레이션 실패: %v
migrate.lfs_mirror_unsupported=LFS 오브젝트에 대한 미러링은 지원하지 않습니다 - 'git lfs fetch --all' 과 'git lfs push -all' 을 대신 사용하세요.
mirror_from=의 미러
forked_from=원본 프로젝트 :
fork_from_self=이미 당신이 소유한 레포지터리를 포크할 수는 없습니다!
copy_link=복사
copy_link_success=복사됨!
copy_link_error=⌘-C 나 Ctrl-C를 눌러 복사
copied=복사 완료
unwatch=보지않기
watch=보기
unstar=좋아요 취소
star=좋아요
fork=포크
download_archive=이 레포지터리 다운로드
no_desc=설명 없음
quick_guide=퀵 가이드
clone_this_repo=이 저장소 복제
create_new_repo_command=커맨드 라인에서 새 레포리지터리 생성
push_exist_repo=커맨드라인에서 기존 레포지터리 푸시
bare_message=이 레포지터리에는 아무것도 없습니다.
code=코드
code.desc=Code는 코드가 담긴 곳입니다.
branch=브렌치
tree=트리
filter_branch_and_tag=브랜치나 태그로 필터
@@ -453,11 +493,15 @@ file_history=히스토리
file_view_raw=원본 보기
file_permalink=고유링크
file_too_large=이 파일은 표시하기엔 너무 큽니다.
video_not_supported_in_browser=브라우저가 HTML5 비디오 태그를 지원하지 않습니다.
stored_lfs=Git LFS에 저장되어 있습니다
commit_graph=커밋 그래프
editor.new_file=파일 생성
editor.upload_file=파일 업로드
editor.edit_file=파일 수정
editor.preview_changes=변경내용 미리보기
editor.cannot_edit_non_text_files=웹 인터페이스에서는 바이너리 파일을 고칠 수 없습니다.
editor.edit_this_file=해당 파일 편집
editor.must_be_on_a_branch=파일 변경을 제안하려면 해당하는 브랜치에 있어야 합니다.
editor.fork_before_edit=파일을 편집 하기 전에 이 저장소를 포크 해야 합니다.
@@ -484,6 +528,7 @@ editor.directory_is_a_file=항목 '%s'의 상위 경로는 이 저장소의 디
editor.file_is_a_symlink=파일 '%s'는 웹 에디터에서 수정할 수 없는 심볼릭 링크입니다
editor.filename_is_a_directory=파일명 '%s'는 이 저장소에 이미 존재하는 디렉토리명입니다.
editor.file_editing_no_longer_exists=편집중인 파일 '%s'는 저장소에 더 이상 존재하지 않습니다.
editor.file_changed_while_editing=수정을 시작한 이후에 파일 내용이 변경되었습니다. <a target="_blank" rel="noopener" href="%s">여기를 눌러</a> 무엇이 변경되었는지 확인하고, 그 변경 사항을 덮어 쓰려면 <strong>커밋 버튼을 다시 한번 누르세요</strong>.
editor.file_already_exists=이 저장소에 이름이 '%s'인 파일이 이미 존재합니다.
editor.no_changes_to_show=표시할 변경사항이 없습니다.
editor.fail_to_update_file=파일 '%s'를 변경/추가 하는데 실패하였습니다. 에러: %v
@@ -502,6 +547,8 @@ commits.message=메시지
commits.date=날짜
commits.older=이전
commits.newer=최신
commits.signed_by=로그인 계정
commits.gpg_key_id=GPG 키 ID
ext_issues=외부 버그
@@ -518,6 +565,7 @@ issues.new.closed_milestone=마일스톤 닫기
issues.new.assignee=담당자
issues.new.clear_assignee=담당자 초기화
issues.new.no_assignee=담당자 없음
issues.no_ref=Branch/Tag 가 지정되어 있지 않습니다.
issues.create=이슈 생성
issues.new_label=새로운 레이블
issues.new_label_placeholder=레이블 이름...
@@ -591,12 +639,28 @@ issues.label_deletion=레이블 삭제
issues.label_deletion_desc=이 라벨을 지우면 모든 이슈에서 이것이 지워집니다. 계속 하시겠습니까?
issues.label_deletion_success=라벨이 성공적으로 삭제 되었습니다!
issues.label.filter_sort.alphabetically=알파벳순
issues.label.filter_sort.reverse_alphabetically=이름 역순으로 정렬
issues.label.filter_sort.by_size=크기
issues.num_participants=참여자 %d명
issues.attachment.open_tab=`클릭하여 "%s" 새탭으로 보기`
issues.attachment.download=' "%s"를 다운로드 하려면 클릭 하십시오 '
issues.subscribe=구독하기
issues.unsubscribe=구독 취소
issues.tracker=시간 추적기
issues.start_tracking_short=시작
issues.start_tracking=시간 추적 시작
issues.start_tracking_history=`%s가 작업 시작`
issues.stop_tracking=중단
issues.stop_tracking_history=`작업 중단 %s`
issues.add_time=수동으로 시간 추가
issues.add_time_short=추가
issues.add_time_cancel=취소
issues.add_time_history=`사용 시간이 추가됨 %s`
issues.add_time_hours=시간
issues.add_time_minutes=
issues.add_time_sum_to_small=시간을 입력하지 않았습니다
issues.cancel_tracking=취소
issues.time_spent_total=총 사용 시간
pulls.new=새 풀 리퀘스트
pulls.compare_changes=변경 사항 비교

View File

@@ -23,6 +23,7 @@ password=Slaptažodis
re_type=Iš naujo įveskite
captcha=Saugos kodas
twofa=Dviejų-žingsnių atpažinimas
passcode=PIN kodas
repository=Saugykla
organization=Organizacija
@@ -31,11 +32,14 @@ new_repo=Nauja saugykla
new_mirror=Naujas veidrodis
new_org=Nauja organizacija
manage_org=Valdyti organizacijas
admin_panel=Administravimo skydelis
account_settings=Paskyros nustatymai
settings=Nustatymai
your_profile=Jūsų profilis
your_settings=Jūsų parametrai
all=Visi
mirrors=Veidrodžiai
activities=Veiklos
issues=Problemos
@@ -64,6 +68,7 @@ run_user=Paleisti vartotoju
domain=Domenas
ssh_port=SSH prievadas
http_port=HTTP prievadas
app_url=Programos URL
log_root_path=Žurnalo kelias
optional_title=Pasirenkami nustatymai
@@ -73,6 +78,7 @@ mailer_password=Siuntėjo slaptažodis
admin_name=Vartotojo vardas
admin_password=Slaptažodis
confirm_password=Patvirtinkite slaptažodį
admin_email=Administratoriaus el. paštas
[home]
uname_holder=Naudotojo vardas ar el. paštas
@@ -158,6 +164,7 @@ delete=Panaikinti paskyrą
twofa=Dviejų faktorių atpažinimas
uid=Uid
public_profile=Viešasis profilis
update_profile=Atnaujinti profilį
continue=Tęsti
cancel=Atšaukti

View File

@@ -49,6 +49,8 @@ your_settings=Uw instellingen
all=Alles
sources=Bronnen
mirrors=Kopieën
collaborative=Samenwerkend
forks=Forks
activities=Activiteiten
@@ -61,6 +63,7 @@ cancel=Annuleren
install=Installatie
title=Initiële configuratie
docker_helper=Als u gebruik maakt van Gitea in Docker, lees dan de <a target="_blank" rel="noopener" href="%s">richtlijnen</a> voordat u iets verandert op deze pagina.
requite_db_desc=Gitea vereist MySQL, MSSQL, PostgreSQL, SQLite3 of TiDB.
db_title=Database-instellingen
db_type=Database-type
host=Server
@@ -114,6 +117,10 @@ federated_avatar_lookup=Federated Avatars zoekopdracht inschakelen
federated_avatar_lookup_popup=Enable federated avatars lookup to use federated open source service based on libravatar.
disable_registration=Schakel zelfregistratie uit
disable_registration_popup=Schakel zelfregistratie uit, alleen admins kunnen accounts maken.
openid_signin=OpenID-inloggen inschakelen
openid_signin_popup=Gebruikerslogin via OpenID inschakelen
openid_signup=OpenID registratie inschakelen
openid_signup_popup=OpenID registratie inschakelen
enable_captcha=Inschakelen Captcha
enable_captcha_popup=Vereis captcha validatie voor zelf-registratie van gebruiker.
require_sign_in_view=Schakel vereiste aanmelding om pagina's te zien in
@@ -138,6 +145,8 @@ default_keep_email_private=Standaardwaarde voor "Houdt Emailadressen Privé
default_keep_email_private_popup=Dit is de standaardwaarde voor de zichtbaarheid van het e-mailadres van gebruikers. Als dit is ingesteld op true zal voor alle nieuwe gebruikers het e-mailadres worden verborgen tot de gebruiker zijn voorkeur aanpast.
default_allow_create_organization=Standaardwaarde voor de machtiging om nieuwe gebruikers organisaties te laten aanmaken
default_allow_create_organization_popup=Dit is de standaardwaarde voor een machtiging die zal worden toegewezen voor nieuwe gebruikers. Als deze is ingesteld op true zullen nieuwe gebruikers de machtiging krijgen om organisaties aan te maken.
default_enable_timetracking=Time tracking standaard inschakelen
default_enable_timetracking_popup=Afhankelijk van deze instelling wordt time tracking automatisch ingeschakeld voor repositories
no_reply_address=No-reply emailadres
no_reply_address_helper=Domein voor het emailadres van gebruikers in git logboeken als hij zijn emailadres privé houdt. Bijvoorbeeld zal gebruiker 'joe' en 'noreply.example.org' worden samengevoegd tot 'joe@noreply.example.org'
@@ -255,11 +264,13 @@ username_been_taken=Gebruikersnaam is al in gebruik.
repo_name_been_taken=Repository naam reeds gebruikt.
org_name_been_taken=Organisatienaam is al in gebruik.
team_name_been_taken=Teamnaam is al in gebruik.
team_no_units_error=Een team moet tenminste één eenheid ingeschakeld hebben.
email_been_used=Emailadres is reeds gebruikt.
openid_been_used=OpenID adres '%s' reeds gebruikt.
username_password_incorrect=Onjuiste gebruikersnaam en/of wachtwoord.
enterred_invalid_repo_name=U heeft een onjuiste repository naam ingevoerd.
enterred_invalid_owner_name=U heeft een onjuiste eigenaar ingevoerd.
enterred_invalid_password=U heeft een onjuist wachtwoord ingevoerd.
user_not_exist=De gebruiker bestaat niet.
last_org_owner=De gebruiker die u probeert te verwijderen is het enige lid (eigenaar) van dit team. U moet eerst een nieuw lid (eigenaar) aanstellen.
cannot_add_org_to_team=Organisatie kan niet worden toegevoegd als een teamlid.
@@ -270,6 +281,8 @@ unable_verify_ssh_key=De ssh sleutel niet kon worden geverifieerd, Controleer he
auth_failed=Verificatie mislukt: %v
still_own_repo=Uw account heeft nog een eigendom op een repository. U moet deze eerst verwijderen of overdragen.
still_has_org=Je account is nog steeds lid van ten minste één organisatie, deze zul je eerst moeten verlaten.
org_still_own_repo=De organisatie is nog eigenaar van een repository. Je moet deze eerst verwijderen of overdragen.
target_branch_not_exist=Doel branch bestaat niet
@@ -361,12 +374,16 @@ manage_ssh_keys=Beheer SSH sleutels
manage_gpg_keys=Beheer GPG sleutels
add_key=Sleutel toevoegen
ssh_desc=Dit is een lijst van alle SSH sleutels die gekoppeld zijn aan uw account. Verwijder alle sleutels die u niet herkent.
gpg_desc=Dit zijn de GPG keys gekoppeld aan je account. Omdat deze sleutels toestaan commits te verifiëren is het belangrijk de bijbehorende private keys veilig te bewaren.
ssh_helper=<strong>Weet u niet hoe?</strong> Lees dan onze handleiding voor het <a href="%s"> genereren van SSH sleutels</a> of voor <a href="%s"> algemene SSH</a> problemen.
gpg_helper=<strong>Hulp nodig?</strong> Neem een kijkje op de GitHub handleiding <a href="%s">over GPG</a>.
add_new_key=SSH sleutel toevoegen
add_new_gpg_key=GPG sleutel toevoegen
ssh_key_been_used=Deze public key wordt al gebruikt.
ssh_key_name_used=Een publieke sleutel met dezelfde naam bestaat al.
gpg_key_id_used=Een publieke GPG-sleutel met dezelfde naam bestaat al.
subkeys=Subkeys
key_id=Key-ID
key_name=Sleutel naam
key_content=Inhoud
add_key_success=Uw SSH-sleutel '%s' is toegevoegd.
@@ -375,6 +392,7 @@ delete_key=Verwijder
ssh_key_deletion=SSH sleutel verwijderen
gpg_key_deletion=GPG-sleutel verwijderen
ssh_key_deletion_desc=Het verwijderen van deze SSH sleutel zal alle verwante toegang tot uw account verwijderen. Wilt u doorgaan?
gpg_key_deletion_desc=Het verwijderen van deze GPG-key zal ervoor zorgen dat alle commits ondertekend met deze key niet meer geverifiëerd zijn. Weet je zeker dat je door wil gaan?
ssh_key_deletion_success=De SSH-sleutel is verwijderd.
gpg_key_deletion_success=De GPG-sleutel is verwijderd.
add_on=Toegevoegd op
@@ -382,24 +400,54 @@ valid_until=Geldig tot en met
valid_forever=Voor altijd geldig
last_used=Laatst gebruikt op
no_activity=Geen recente activiteiten
can_read_info=Lezen
can_write_info=Schrijven
key_state_desc=Deze sleutel werd gebruikt in de laatste 7 dagen
token_state_desc=Dit token werd gebruikt in de laatste 7 dagen
show_openid=Tonen op profiel
hide_openid=Verbergen van profiel
ssh_disabled=SSH is uitgeschakeld
manage_social=Beheer gekoppelde sociale accounts
social_desc=Dit is een lijst van gekoppelde social accounts. Controleer of alle accounts bekend voorkomen gezien deze kunnen worden gebruikt om in te loggen op je account.
unbind=Loskoppelen
unbind_success=Social account is ontkoppeld van je account.
manage_access_token=Persoonlijke toegangstokens beheren
generate_new_token=Nieuw Token genereren
tokens_desc=Tokens die je hebt gegenereerd om toegang tot de Gitea APIs te verkrijgen.
new_token_desc=Alle tokens hebben volledig toegang tot uw account.
token_name=Symbolische naam
generate_token=Token genereren
generate_token_success=Nieuw toegangstoken is met succes gegenereerd! Kopieer je toegangstoken nu. Dit is de enige keer dat je dit toegangstoken te zien krijgt!
delete_token=Verwijderen
access_token_deletion=Persoonlijke toegangstoken verwijderen
access_token_deletion_desc=Het verwijderen van dit toegangstoken zal de toegang van iedere applicatie gebruik makende van dit token intrekken. Weet je zeker dat je door wil gaan?
delete_token_success=Het toegangstoken is verwijderd. Vergeet niet om enige applicaties gebruik makende van dit token aan te passen.
twofa_desc=Gitea ondersteunt two-factor authenticatie om de beveiliging van je account te verbeteren.
twofa_is_enrolled=Je account is momenteel <strong>ingeschreven</strong> voor two-factor authenticatie.
twofa_not_enrolled=Je account is momenteel niet ingeschreven voor two-factor authenticatie.
twofa_disable=Two-factor authenticatie uitschakelen
twofa_scratch_token_regenerate=Genereer een nieuwe herstelcode
twofa_scratch_token_regenerated=Je herstelcode is opnieuw gegenereerd. Deze is nu %s. Bewaar deze op een veilige plek.
twofa_enroll=Two-factor authenticatie inschakelen
twofa_disable_note=Indien nodig kan two-factor authenticatie worden uitgeschakeld.
twofa_disable_desc=Het uitschakelen van two-factor authenticatie verminderd de beveiliging van je account. Weet je zeker dat je door wil gaan?
regenerate_scratch_token_desc=Als je je herstelcode bent verloren, of als je deze al hebt gebruikt om in te loggen, kun je deze hier opnieuw instellen.
twofa_disabled=Two-factor authenticatie is uitgeschakeld.
scan_this_image=Scan deze afbeelding met je authenticatie applicatie:
or_enter_secret=Of voer deze geheime code in: %s
then_enter_passcode=En voer de code in die je authenticatie applicatie geeft:
passcode_invalid=De code is niet correct. Probeer het nogmaals.
twofa_enrolled=Je account is nu ingeschreven voor two-factor authenticatie. Bewaar je eenmalige herstelcode (%s) goed, dit is de enige keer dat deze getoond wordt!
manage_account_links=Onderhoud account koppelingen
manage_account_links_desc=Externe accounts gekoppeld aan dit account
account_links_not_available=Er zijn momenteel geen externe accounts gekoppeld aan dit account
remove_account_link=Gekoppeld account verwijderen
remove_account_link_desc=Het verwijderen van dit gekoppelde account zal alle toegang van dit account intrekken. Weet je zeker dat je door wil gaan?
remove_account_link_success=Account koppeling is succesvol verwijderd!
orgs_none=U bent geen lid van een organisatie.
repos_none=U bezit geen repositories
@@ -440,6 +488,8 @@ mirror_last_synced=Laatste synchronisatie
watchers=Volgers
stargazers=Stargazers
forks=Forks
pick_reaction=Kies je reactie
reactions_more=en %d meer
form.reach_limit_of_creation=U hebt uw limiet van %d repositories al bereikt.
form.name_reserved=Repositorienaam '%s' is gereserveerd.
@@ -478,6 +528,7 @@ bare_message=Deze repository bevat geen inhoud.
code=Code
branch=Branch
tree=Tree
filter_branch_and_tag=Filter op branch of tag
branches=Branches
tags=Labels
@@ -486,10 +537,12 @@ pulls=Pull-aanvragen
labels=Labels
milestones=Mijlpalen
commits=Commits
commit=Commit
releases=Publicaties
file_raw=Ruw
file_history=Geschiedenis
file_view_raw=Weergave ruw bestand
file_permalink=Permalink
file_too_large=Dit bestand is te groot om te tonen
video_not_supported_in_browser=Uw browser ondersteunt geen HTML5 video.
stored_lfs=Opgeslagen met Git LFS
@@ -507,6 +560,7 @@ editor.file_delete_success=Bestand '%s' is succesvol verwijderd!
editor.name_your_file=Bestandsnaam...
editor.or=of
editor.cancel_lower=annuleer
editor.commit_changes=Wijzigingen doorvoeren
editor.add_tmpl='%s/<filename>' toevoegen
editor.add='%s' toevoegen
editor.update='%s' updaten
@@ -536,6 +590,7 @@ commits.message=Bericht
commits.date=Datum
commits.older=Ouder
commits.newer=Nieuwer
commits.signed_by=Getekend door
issues.new=Nieuw probleem
@@ -878,6 +933,7 @@ diff.show_diff_stats=Toon Diff Stats
diff.show_split_view=Zij-aan-zij weergave
diff.show_unified_view=Gecombineerde weergave
diff.stats_desc=<strong>%d gewijzigde bestanden</strong> met <strong>toevoegingen van %d</strong> en <strong>%d verwijderingen</strong>
diff.bin=BIN
diff.view_file=Bestand weergeven
diff.file_suppressed=Diff onderdrukt omdat het te groot bestand

View File

@@ -8,7 +8,7 @@ sign_in=Вход
sign_in_with=Войдите с помощью
sign_out=Выход
sign_up=Регистрация
link_account=Привязать Аккаунт
link_account=Привязать аккаунт
link_account_signin_or_signup=Войдите с уже существующими учётными данными или зарегистрируйтесь для связи с этим аккаунтом
register=Регистрация
website=Веб-сайт
@@ -76,7 +76,7 @@ path=Путь
sqlite_helper=Путь к файлу базы данных SQLite3 или TiDB. <br>Укажите абсолютный путь при запуске в качестве службы.
err_empty_db_path=Путь к базе данных SQLite3 или TiDB не может быть пустым.
err_invalid_tidb_name=Имя базы данных TiDB не может содержать символы "." и "-".
no_admin_and_disable_registration=Вы не можете отключить регистрацию до создания учетной записи администратора.
no_admin_and_disable_registration=Вы не можете отключить регистрацию до создания учётной записи администратора.
err_empty_admin_password=Пароль администратора не может быть пустым.
general_title=Общие параметры приложения
@@ -102,7 +102,7 @@ log_root_path_helper=Каталог для записи файлов журна
optional_title=Расширенные настройки
email_title=Настройки службы электронной почты
smtp_host=Узел SMTP
smtp_from=Из
smtp_from=От
smtp_from_helper=Почта от адреса, RFC 5322. Это может быть email адрес или формат "Имя" <email@example.com>.
mailer_user=Отправитель
mailer_password=Пароль отправителя
@@ -125,7 +125,7 @@ enable_captcha=Включить капчу
enable_captcha_popup=Запрашивать капчу при регистрации пользователя.
require_sign_in_view=Разрешить требовать авторизацию для просмотра страниц
require_sign_in_view_popup=Только пользователи Gitea могут просматривать страницы, прочие посетители смогут увидеть только ссылку на авторизацию вверху страницы.
admin_setting_desc=Вы не должны создать учетную запись администратора прямо сейчас, первый пользователь получит доступ с правами администратора автоматически.
admin_setting_desc=Вы не обязаны создавать учётную запись администратора прямо сейчас, первый пользователь получит доступ с правами администратора автоматически.
admin_title=Настройки учётной записи администратора
admin_name=Имя пользователя
admin_password=Пароль

View File

@@ -0,0 +1,106 @@
[install]
[home]
[explore]
[auth]
[mail]
[modal]
[form]
[user]
[settings]
[repo]
[org]
[admin]
[action]
[tool]
[dropzone]
[notification]
[gpg]
[units]

View File

@@ -20,6 +20,7 @@ notifications=Notiser
create_new=Skapa...
user_profile_and_more=Användarprofil med mera
signed_in_as=Inloggad som
enable_javascript=Denna hemsida fungerar bättre med JavaScript
username=Användarnamn
email=E-post
@@ -46,6 +47,11 @@ your_profile=Din profil
your_starred=Dina Stjärnmärkta
your_settings=Dina inställningar
all=Alla
sources=Källor
mirrors=Speglar
collaborative=Kollaborativa
forks=Forks
activities=Aktiviteter
pull_requests=Pull förfrågningar
@@ -57,6 +63,7 @@ cancel=Avbryt
install=Installation
title=Inledande konfiguration
docker_helper=Om du kör Gitea inuti Docker, vänligen läs <a target="_blank" rel="noopener" href="%s">riktninjerna</a> noggrant innan du ändrar någonting på denna sida.
requite_db_desc=Gitea kräver MySQL, MSSQL, PostgreSQL, SQLite3 eller TiDB.
db_title=Databasinställningar
db_type=Databastyp
host=Server
@@ -110,6 +117,10 @@ federated_avatar_lookup=Aktivera förenad uppslagning av avatarer
federated_avatar_lookup_popup=Använd libravatar vid förenad uppslagning av avatarer.
disable_registration=Stäng av självregistrering
disable_registration_popup=Stäng av självregistrering av användare, endast administratören kan skapa konton.
openid_signin=Aktivera OpenID-inloggning
openid_signin_popup=Aktivera användarinloggning via OpenID
openid_signup=Aktivera OpenID självregistrering
openid_signup_popup=Aktivera OpenID-baserad självregistrering
enable_captcha=Aktivera Captcha
enable_captcha_popup=Kräv captcha för användarregistrering.
require_sign_in_view=Kräv inloggning för att visa sidor
@@ -235,6 +246,8 @@ Content=Innehåll
require_error=får inte vara tomt
alpha_dash_error=` får bara innehålla bokstäver, nummer och bindestreck (-_).`
alpha_dash_dot_error=` får bara innehålla bokstäver, nummer, bindestreck (-_) och punkt`
git_ref_name_error='måste vara ett för git välformaterat referensnamn.'
size_error=` måste vara av storleken %s`
min_size_error=` måste innehålla minst %s tecken.`
max_size_error=` får inte innehålla mer än %s tecken.`
@@ -246,20 +259,26 @@ captcha_incorrect=Captcha stämmer inte överens.
password_not_match=Dina valda lösenord matchar inte.
username_been_taken=Användarnamnet är upptaget.
repo_name_been_taken=Utvecklingskatalogsnamnet är upptaget.
org_name_been_taken=Organisationsnamnet är upptaget.
team_name_been_taken=Gruppnamnet är upptaget.
team_no_units_error=Laget måste ha minst en enhet aktiverad.
email_been_used=E-postadress används redan.
openid_been_used=OpenID-adressen '%s' används redan.
username_password_incorrect=Felaktigt användarnamn eller lösenord.
enterred_invalid_repo_name=Se till att utvecklingskatalogsnamet du angav är rätt.
enterred_invalid_owner_name=Kontrollera att ägarnamnet som du angav är rätt.
enterred_invalid_password=Kontrollera att lösenordet du angav är rätt.
user_not_exist=Användaren finns inte.
last_org_owner=Att ta bort den sista användaren i ägare-teamet är inte tillåtet då det måste finnas minst en användare i ägare-teamet.
cannot_add_org_to_team=En organisation kan inte läggas till som en gruppmedlem.
invalid_ssh_key=Tyvärr, din SSH-nyckel: %s kan inte verifieras
invalid_gpg_key=Tyvärr, din GPG-nyckel: %s kan inte verifieras
unable_verify_ssh_key=SSH-nyckeln kunde ej verifieras; Vänligen dubbelkolla om du gjort något misstag.
auth_failed=Autentisering misslyckades: %v
still_own_repo=Ditt konto har fortfarande ägandeskap över minst en utvecklingskatalog. Du måste ta bort eller överföra dem först.
still_has_org=Ditt konto fortfarande är fortfarande medlem i minst en organisation, du måste lämna dem först.
org_still_own_repo=Denna organisation har fortfarande ägandeskap över en eller flera utvecklingskataloger, du måste ta bort eller överföra dem först.
@@ -282,11 +301,13 @@ form.name_pattern_not_allowed=Användarnamnet '%s' är inte tillåtet.
[settings]
profile=Profil
password=Lösenord
security=Säkerhet
avatar=Visningsbild
ssh_gpg_keys=SSH / GPG-nycklar
social=Sociala konton
applications=Applikationer
orgs=Organisationer
repos=Utvecklingskataloger
delete=Radera konto
twofa=Tvåfaktorsautentisering
account_link=Externa konton
@@ -302,6 +323,7 @@ location=Plats
update_profile=Uppdatera profil
update_profile_success=Din profil har uppdaterats.
change_username=Användarnamn ändrat
change_username_prompt=Denna ändring kommer att ändra länkarna till ditt konto.
continue=Fortsätt
cancel=Avbryt
@@ -320,6 +342,7 @@ new_password=Nytt lösenord
retype_new_password=Skriv ditt nya lösenord igen
password_incorrect=Nuvarande lösenord är felaktigt.
change_password_success=Ditt lösenord har ändrats. Du kan nu logga in med ditt nya lösenord.
password_change_disabled=Icke-lokala användare kan inte ändra sitt lösenord via webbgränssnittet.
emails=E-postadresser
manage_emails=Hantera e-postadresser
@@ -329,19 +352,25 @@ primary=Primär
primary_email=Ställ in som primär
delete_email=Radera
email_deletion=Ta bort e-post
email_deletion_desc=Radering av denna epost-adress kommer ta bort all relaterad information från ditt konto. Git commits som använder denna epost-adress förblir oförändrade. Vill du fortsätta?
email_deletion_success=Epostaddressen har tagits bort!
openid_deletion_desc=Igenom att ta bort denna OpenID-adress från ditt konto kommer du inte kunna logga in med det i framtiden. Är du säker på att du vill fortsätta?
openid_deletion_success=OpenID har tagits bort!
add_new_email=Lägg till ny e-postadress
add_new_openid=Lägg till ny OpenID URI
add_email=Lägga till e-post
add_openid=Lägg till OpenID URI
add_email_confirmation_sent=Ett nytt bekräftelsemail har skickats till '%s', kontrollera vänligen din inkorg inom dom närmsta %d timmarna för att slutföra bekräftelsen.
add_email_success=Din nya epostaddress har lagts till.
add_openid_success=Din nya OpenID-adress har lagts till.
keep_email_private=Håll Epostadressen Gömd
keep_email_private_popup=Om denna inställningar är påslagen kommer din epostaddress att hållas gömd från andra användare.
openid_desc=Med OpenID-adresser kan du delegera autentisering mot en leverantör av ditt eget val
manage_ssh_keys=Hantera SSH-nycklar
manage_gpg_keys=Hantera GPG-nycklar
add_key=Lägg till nyckel
ssh_desc=Detta är de SSH-nycklar som associerats med ditt konto. Eftersom dessa nycklar tillåter brukaren att få tillgång till din utvecklingskatalog, är det mycket viktigt att kontrollera att dom är dina.
gpg_desc=Dessa GPG-nycklar är associerade med ditt konto. Eftersom dessa nycklar tillåter revisioner att verifieras är det mycket viktigt att du håller den motsvarande privata nyckeln säker.
ssh_helper=<strong>Behöver du hjälp?</strong> Kolla in Github's guide för att <a href="%s">skapa din egen SSH-nycklar</a> eller lösa <a href="%s">vanliga problem</a> som kan uppstå med SSH.
gpg_helper=<strong>Behöver du hjälp?</strong> Ta en titt på Github's guide <a href="%s"> om GPG</a>.
@@ -350,6 +379,7 @@ add_new_gpg_key=Lägg till GPG-nyckel
ssh_key_been_used=Denna offentliga nyckel används redan.
ssh_key_name_used=En offentlig nyckel med samma namn existerar redan.
gpg_key_id_used=En offentlig GPG-nyckel med samma id existerar redan.
gpg_no_key_email_found=Ingen av de epostadresser kopplade till GPG-nyckeln kunde hittas.
subkeys=Undernycklar
key_id=Nyckel-ID
key_name=Nyckelnamn
@@ -365,12 +395,16 @@ ssh_key_deletion_success=SSH-nyckeln har tagits bort.
gpg_key_deletion_success=GPG-nyckeln har tagits bort.
add_on=Tillagd
valid_until=Giltig t.om.
valid_forever=Giltig för alltid
last_used=Användes senast
no_activity=Ingen nylig aktivitet
can_read_info=Läs
can_write_info=Skriv
key_state_desc=Denna nyckel har använts inom dom senaste 7 dagarna
token_state_desc=Denna token har används inom dom senaste 7 dagarna
show_openid=Synlig på min profil
hide_openid=Dold från min profil
ssh_disabled=SSH är inaktiverat
manage_social=Hantera länkade sociala konton
social_desc=Detta är en lista över associerade sociala konton. Av säkerhetsskäl, vänligen verifiera att du igen alla dessa konton, eftersom de kan användas för att logga in på ditt konto.
@@ -414,6 +448,7 @@ remove_account_link_desc=Borttagning av det länkade kontot kommer att återkall
remove_account_link_success=Kontolänk borttagen!
orgs_none=Du är inte en medlem i någon organisation.
repos_none=Du har inga utvecklingskataloger associerade med ditt konto
delete_account=Radera ditt konto
delete_prompt=Åtgärden kommer at ta bort ditt konto permanent, och kan <strong>INTE</strong> ångras!
@@ -453,8 +488,12 @@ mirror_last_synced=Senast synkad
watchers=Observerare
stargazers=Stjärnmärkare
forks=Förgreningar
pick_reaction=Välj din reaktion
reactions_more=och %d flera
form.reach_limit_of_creation=Du har redan nått gränsen av %d repos.
form.name_reserved=Utvecklingskatalogsnamnet '%s' är reserverat.
form.name_pattern_not_allowed=Utvecklingskatalogsnamnet '%s' är inte tillåtet.
need_auth=Tillstånd Krävs
migrate_type=Migreringstyp
@@ -466,9 +505,11 @@ migrate.clone_local_path=eller sökvägen på den lokala servern
migrate.permission_denied=Du får inte importera lokala repon.
migrate.invalid_local_path=Ogiltig lokal sökväg, den finns inte eller är inte en katalog.
migrate.failed=Migrering misslyckades: %v
migrate.lfs_mirror_unsupported=Att spegla LFS objekt stöds ej - Använd ' git lfs fetch --all ' och 'git lfs push --all' istället.
mirror_from=spegling av
forked_from=forkad från
fork_from_self=Du kan inte forka en utvecklingskatalog som du redan äger!
copy_link=Kopiera
copy_link_success=Kopierad!
copy_link_error=Tryck på ⌘-C eller Ctrl-C för att kopiera
@@ -483,8 +524,12 @@ download_archive=Ladda ned utvecklingskatalogen
no_desc=Ingen beskrivning
quick_guide=Snabbguide
clone_this_repo=Klona detta repo
create_new_repo_command=Skapa en ny utvecklingskatalog på kommandoraden
push_exist_repo=Pusha en existerande utvecklingskatalog från kommandoraden
bare_message=Denna utvecklingskatalog är tom.
code=Kod
code.desc=Kod är där koden lagras
branch=Gren
tree=Träd
filter_branch_and_tag=Filtrera gren eller tagg
@@ -495,6 +540,7 @@ pulls=Pull-förfrågningar
labels=Etiketter
milestones=Milstenar
commits=Incheckningar
commit=Commit
releases=Släpp
file_raw=
file_history=Historik
@@ -503,6 +549,7 @@ file_permalink=Permalänk
file_too_large=Denna fil är för stor för att visas
video_not_supported_in_browser=Min webbläsare stödjer inte HTML5 video-tagg.
stored_lfs=Sparad med Git LFS
commit_graph=Commit-graf
editor.new_file=Ny fil
editor.upload_file=Ladda upp fil
@@ -650,6 +697,10 @@ issues.attachment.open_tab=`Klicka för att se "%s" i en ny flik`
issues.attachment.download=`Klicka för att hämta "%s"`
issues.subscribe=Prenumerera
issues.unsubscribe=Avsluta prenumerationen
issues.add_time_hours=Timmar
issues.add_time_minutes=Minuter
issues.add_time_sum_to_small=Ingen tid har angetts
issues.time_spent_total=Total tid spenderad
pulls.new=Ny Pull-Förfrågan
pulls.compare_changes=Jämför Ändringar
@@ -723,6 +774,24 @@ wiki.page_already_exists=Wiki-sida med samma namn finns redan.
wiki.pages=Sidor
wiki.last_updated=Senast uppdaterad %s
activity.period.filter_label=Period:
activity.period.daily=1 dag
activity.period.halfweekly=3 dagar
activity.period.weekly=1 vecka
activity.period.monthly=1 månad
activity.overview=Översikt
activity.title.user_1=%d användare
activity.title.user_n=%d användare
activity.active_issues_count_1=<strong>%d</strong> Aktivt ärende
activity.active_issues_count_n=<strong>%d</strong> Aktiva ärenden
activity.closed_issues_count_1=Stängt ärende
activity.closed_issues_count_n=Stängda ärenden
activity.title.issues_1=%d ärende
activity.title.issues_n=%d Ärenden
activity.title.issues_closed_by=%s stängd av %s
activity.title.issues_created_by=%s skapad av %s
activity.closed_issue_label=Stängd
activity.new_issues_count_1=Nytt ärende
settings=Inställningar
@@ -776,8 +845,12 @@ settings.wiki_deletion_success=Repots wikidata har tagits bort.
settings.delete=Ta Bort Detta Repo
settings.delete_desc=När du har tagit bort ett repo så finns det ingen återvändo. Var säker på vad du gör.
settings.delete_notices_1=- Denna åtgärd kan <strong>INTE</strong> ångras.
settings.delete_notices_fork_1=- Alla forkar kommer bli oberoende efter borttagning.
settings.deletion_success=Utvecklingskatalogen har tagits bort.
settings.update_settings_success=Utvecklingskatalogens inställningar har uppdaterats.
settings.transfer_owner=Ny Ägare
settings.make_transfer=Överför
settings.transfer_succeed=Ägarskapet för utvecklingskatalogen har överförts.
settings.confirm_delete=Bekräfta Borttagelsen
settings.add_collaborator=Lätt Till Ny Kollaboratör
settings.add_collaborator_success=Ny kollaboratör har blivit tillagd.
@@ -790,6 +863,7 @@ settings.org_not_allowed_to_be_collaborator=Organisationen kan inte läggas till
settings.user_is_org_member=Änvändaren är en organisationsmedlem som inte kan bli tillagd som deltagare.
settings.add_webhook=Lägg Till Webbhook
settings.webhook_deletion=Ta Bort Webbhook
settings.webhook_deletion_desc=Borttagning av denna webbhook kommer att ta bort all dess information och all leveranshistorik. Är du säker på att du vill fortsätta?
settings.webhook_deletion_success=Webbhook har tagits bort!
settings.webhook.test_delivery=Testa Leverans
settings.webhook.test_delivery_desc=Skicka en falsk pushhändelse för att testa dina webbhook-inställningar
@@ -808,6 +882,8 @@ settings.content_type=Typ av innehåll
settings.secret=Hemlighet
settings.slack_username=Användarnamn
settings.slack_icon_url=URL för ikon
settings.discord_username=Användarnamn
settings.discord_icon_url=URL för ikon
settings.slack_color=Färg
settings.event_desc=När ska Webhooken köras?
settings.event_push_only=Endast <code>push</code>-eventet.
@@ -819,6 +895,8 @@ settings.event_pull_request=Hämtningsbegäran
settings.event_pull_request_desc=Hämtningsbegäran öppnad, stängd, återöppnad, redigerad, tilldelad, otilldelad, etikett uppdaterad, etikett rensad eller synkroniserad.
settings.event_push=Pusha
settings.event_push_desc=Uppladdning till ett förråd
settings.event_repository=Utvecklingskatalog
settings.event_repository_desc=Utvecklingskatalogen skapad eller borttagen
settings.active=Aktiv
settings.add_hook_success=Ny webbkrok har lagts till.
settings.update_webhook=Uppdatera Webhook

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,513 @@
app_desc=Зручний сервіс власного Git хостінгу, написаний на Go
home=Головна
dashboard=Панель інструментів
explore=Огляд
help=Довідка
sign_in=Увійти
sign_in_with=Увійти через
sign_out=Вийти
sign_up=Зареєструватися
register=Реєстрація
website=Web-сайт
version=Версія
page=Сторінка
template=Шаблон
language=Мова
notifications=Сповіщення
create_new=Створити...
user_profile_and_more=Профіль користувача та інше
signed_in_as=Увійшов як
enable_javascript=Цей веб-сайт працює краще з JavaScript
username=Ім'я кристувача
email=Електронна пошта
password=Пароль
re_type=Повторіть
captcha=Captcha
twofa=Двофакторна авторизація
passcode=Код доступу
repository=Репозиторій
organization=Організація
mirror=Дзеркало
new_repo=Новий репозиторій
new_migrate=Нова міграція
new_mirror=Нове дзеркало
new_fork=Новий репозиторій - копія
new_org=Нова організація
manage_org=Керування організаціями
admin_panel=Панель адміністратора
account_settings=Параметри облікового запису
settings=Параметри
your_profile=Ваш профіль
your_starred=Ваші улюблені
your_settings=Ваші налаштування
all=Усі
sources=Джерела
mirrors=Дзеркала
collaborative=Співпраця
forks=Відгалуження
pull_requests=Запити до злиття
issues=Питання
cancel=Відміна
[install]
install=Встановлення
user=Користувач
password=Пароль
db_name=Ім'я бази даних
db_helper=Будь ласка, використовуйте MySQL як INNODB з таблицею символів utf8_general_ci.
ssl_mode=Режим SSL
path=Шлях
err_invalid_tidb_name=Ім'я бази даних TiDB не може містити символів "." і "-".
no_admin_and_disable_registration=Ви не можете заборонити реєстрацію без створення облікового запису адміністратора.
err_empty_admin_password=Пароль адміністратора не може бути пустим.
general_title=Основні налаштування програми
app_name=Назва програми
repo_path=Кореневий шлях репозиторія
domain=Домен
ssh_port=SSH порт
http_port=Порт HTTP
app_url=URL адреса програми
optional_title=Додаткові налаштування
smtp_host=SMTP хост
smtp_from=Від
mailer_password=Відправник паролю
register_confirm=Увімкнути підтвердження реєстрації
mail_notify=Увімкнути сповіщення електронною поштою
server_service_title=Налаштування сервера та інших сервісів
offline_mode=Увімкнути автономний режим
offline_mode_popup=Відключити CDN, так що всі файли ресурсів розміщуються локально.
disable_gravatar=Вимкнути сервіс Gravatar
disable_gravatar_popup=Виключити Gravatar та інші зовнішні джерела, всі аватари або завантажуються користувачами або використовується аватар за замовчанням.
federated_avatar_lookup=Увімкнути зовнішні аватари
federated_avatar_lookup_popup=Увімкнути зовнішний Аватар за допомогою Libravatar.
disable_registration=Вимкнути самостійну реєстрацію
disable_registration_popup=Вимкнути самостійну реєстрацію користувачів, тільки адміністратор може створювати облікові записи.
openid_signin=Увімкнути реєстрацію за допомогою OpenID
openid_signin_popup=Увімкнути вхід за допомогою OpenID
openid_signup=Увімкнути самостійну реєстрацію за допомогою OpenID
openid_signup_popup=Увімкнути самостійну реєстрацію за допомогою OpenID
enable_captcha=Увімкнути Captcha
enable_captcha_popup=Вимагати перевірку CAPTCHA при самостійній реєстрації користувача.
require_sign_in_view=Увімкнути вимогу авторизації для перегляду сторінок
require_sign_in_view_popup=Тільки авторизовані користувачі можуть переглядати сторінки, гості зможуть бачити тільки сторінку авторизації.
admin_setting_desc=Ви не мусите створювати обліковий запис адміністратора прямо зараз, користувач з Id=1 отримає доступ адміністратора автоматично.
admin_title=Налаштування облікового запису адміністратора
admin_name=Ім'я кристувача
admin_password=Пароль
confirm_password=Підтвердження пароля
admin_email=Email адміністратора
install_btn_confirm=Встановлення Gitea
test_git_failed=Не в змозі перевірити 'git' команду: %v
sqlite3_not_available=Ваша версія не підтримує SQLite3, будь ласка завантажте офіційну бінарну версію з %s, не gobuild версію.
invalid_db_setting=Помилкова настройка бази даних: %v
invalid_repo_path=Неприпустимий шлях до сховища репозиторіїв: %v
run_user_not_match=Користувач, що здійснює запуск, не відповідає поточному: %s -> %s
save_config_failed=Не в змозі зберегти конфігурацію: %v
invalid_admin_setting=Неприпустимі налаштування облікового запису адміністратора: %v
install_success=Прошу! Дякуємо вам за вибір Gitea. Розважайтеся. І будьте обережні!
default_allow_create_organization=Значення за замовчуванням для нових користувачів при створенні організації
default_enable_timetracking=Увімкнути відстеження часу за замовчуванням
[home]
uname_holder=Ім'я користувача або електронна пошта
password_holder=Пароль
switch_dashboard_context=Змінити дошку
my_repos=Мої репозиторії
show_more_repos=Показати більше репозиторіїв...
collaborative_repos=Спільні репозиторії
my_orgs=Мої організації
my_mirrors=Мої дзеркала
view_home=Переглянути %s
issues.in_your_repos=В ваших репозиторіях
[explore]
repos=Репозиторії
users=Користувачі
organizations=Організації
search=Пошук
[auth]
create_new_account=Створити обліковий запис
register_helper_msg=Вже зареєстровані? Увійдіть зараз!
social_register_helper_msg=Вже зареєстровані? Увійдіть зараз!
disable_register_prompt=Вибачте, реєстрація відключена. Будь ласка, зв'яжіться з адміністратором сайту.
disable_register_mail=На жаль, підтвердження реєстрації на електрону пошту було відключено.
remember_me=Запам'ятати мене
forgot_password_title=Забув пароль
forgot_password=Забули пароль?
sign_up_now=Потрібен обліковий запис? Зареєструватися зараз.
active_your_account=Активувати обліковий запис
prohibit_login=Вхід заборонений
reset_password=Скинути пароль
invalid_code=На жаль, код підтвердження, закінчився або помилковий.
reset_password_helper=Натисніть тут для скидання пароля
password_too_short=Довжина пароля не може бути меншою за %d.
verify=Підтвердити
login_userpass=Користувач / Пароль
login_openid=OpenID
openid_connect_submit=Під’єднатися
openid_connect_title=Підключитися до існуючого облікового запису
openid_register_title=Створити новий обліковий запис
disable_forgot_password_mail=Вибачте, скидання паролю відключене. Будь ласка, зв'яжіться з адміністратором сайту.
[mail]
activate_account=Будь ласка, активуйте ваш обліковий запис
activate_email=Підтвердить вашу адресу електронної пошти
reset_password=Відновити ваш пароль
register_success=Реєстрація успішна
register_notify=Ласкаво просимо у Gitea
[modal]
yes=Так
no=Ні
modify=Змінити
[form]
UserName=Ім’я користувача
RepoName=Назва репозиторію
Email=Адреса електронної пошти
Password=Пароль
Retype=Введіть пароль ще раз
SSHTitle=Iм'я SSH ключа
HttpsUrl=Адреса HTTPS
TeamName=Назва команди
AuthName=Назва авторизації
AdminEmail=Email адміністратора
NewBranchName=Ім'я нової гілки
CommitSummary=Резюме коміту
CommitMessage=Повідомлення коміту
TreeName=Шлях до файлу
Content=Зміст
require_error=` не може бути пустим.`
alpha_dash_error=` має складатись з буков, цифр, або рисок(-_).`
alpha_dash_dot_error=` має складатись з буков, цифр, рисок(-_), або крапок.`
unknown_error=Невідома помилка:
username_been_taken=Ім'я користувача вже використовується.
repo_name_been_taken=Назва репозіторію вже використовується.
org_name_been_taken=Назва організації вже використовується.
team_name_been_taken=Назва команди вже використовується.
user_not_exist=Даний користувач не існує.
[user]
change_avatar=Змінити свій аватар
join_on=Приєднався
repositories=Репозиторії
activity=Публічна активність
followers=Підписники
starred=Позначені зірочками репозиторії
following=Слідкувати
follow=Підписатися
unfollow=Відписатися
form.name_reserved=Ім'я користувача "%s" зарезервовано.
[settings]
profile=Профіль
password=Пароль
security=Безпека
avatar=Аватар
social=Соціальні акаунти
applications=Програми
orgs=Організації
repos=Репозиторії
delete=Видалити обліковий запис
twofa=Двофакторна авторизація
organization=Організація
uid=Ідентифікатор Uid
public_profile=Загальнодоступний профіль
full_name=Повне ім'я
website=Web-сайт
location=Місцезнаходження
update_profile=Оновити профіль
update_profile_success=Профіль успішно оновлено.
change_username=Ім'я користувача змінено
continue=Продовжити
cancel=Відміна
lookup_avatar_by_mail=Знайти аватар за адресою ел. пошти
change_password=Змінити пароль
old_password=Поточний пароль
new_password=Новий пароль
retype_new_password=Введіть новий пароль іще раз
password_incorrect=Поточний пароль помилковий.
emails=Адреса електронної пошти
manage_emails=Управління адресами електронної пошти
primary=Основний
primary_email=Встановити головним
delete_email=Видалити
email_deletion=Видалити Email
add_new_email=Додати нову адресу електронної пошти
add_key=Додати ключ
key_content=Зміст
delete_key=Видалити
add_on=Додано
last_used=Останнє використання
no_activity=Жодної діяльності
can_read_info=Читати
can_write_info=Написати
key_state_desc=Цей ключ використовувався в останні 7 днів
token_state_desc=Цей токен використовувався в останні 7 днів
show_openid=Показати у профілю
hide_openid=Не показувати у профілі
delete_token=Видалити
delete_account=Видалити ваш обліковий запис
confirm_delete_account=Підтвердження видалення
delete_account_title=Видалення облікового запису
[repo]
owner=Власник
repo_name=Назва репозиторію
repo_name_helper=Гарна назва репозиторія зазвичай складається з коротких та унікальних ключових слів, які легко запам'ятати.
visibility=Видимість
fork_repo=Відгалужити репозиторій
fork_from=Відгалужена з
repo_desc=Опис
repo_lang=Мова
license=Ліцензія
create_repo=Створити репозиторій
default_branch=Головна гілка
migrate_type=Тип міграції
migrate_repo=Перенесення репозиторія
forked_from=відгалужено від
copy_link=Копіювати
copy_link_success=Скопійовано!
copied=Скопійовано
unwatch=Не стежити
watch=Слідкувати
unstar=Зняти зірку
star=Зірка
fork=Відгалуження
download_archive=Скачати цей репозиторій
no_desc=Без опису
quick_guide=Короткий посібник
clone_this_repo=Кнонувати цей репозиторій
create_new_repo_command=Створити новий репозиторій з командного рядка
push_exist_repo=Опублікувати існуючий репозиторій з командного рядка
code=Код
branch=Гілка
tree=Дерево
filter_branch_and_tag=Фільтрувати гілку або тег
branches=Гілки
tags=Теги
issues=Питання
pulls=Запити до злиття
labels=Мітки
milestones=Етап
commits=Зміни
commit=Змина
releases=Релізи
file_raw=Raw
file_history=Історія
file_view_raw=Перегляд Raw
file_permalink=Постійне посилання
editor.new_file=Новий файл
editor.upload_file=Завантажити файл
editor.edit_file=Редагування файла
editor.preview_changes=Попередній перегляд змін
editor.edit_this_file=Редагувати цей файл
editor.delete_this_file=Видалити цей файл
editor.name_your_file=Дайте назву файлу...
editor.or=або
editor.cancel_lower=відміна
editor.commit_changes=Зафіксувати зміни
editor.cancel=Відміна
commits.commits=Зміни
commits.search=Знайти зміни
commits.find=Пошук
commits.search_all=Усі гілки
commits.author=Автор
commits.message=Повідомлення
commits.date=Дата
commits.older=Давніше
commits.newer=Новіше
issues.new=Нове обговорення
issues.new.labels=Мітки
issues.new.no_label=Без Мітки
issues.new.clear_labels=Очистити мітки
issues.new.milestone=Етап
issues.new.no_milestone=Етап відсутній
issues.new.clear_milestone=Очистити етап
issues.new.open_milestone=Активні етапи
issues.new.closed_milestone=Закриті етапи
issues.new.assignee=Призначено
issues.new.clear_assignee=Прибрати відповідального
issues.new.no_assignee=Немає відповідального
issues.new_label=Нова мітка
issues.new_label_placeholder=Назва мітки...
issues.create_label=Створити мітку
issues.label_templates.helper=Оберіть набір міток
issues.label_templates.use=Використовуйте набір міток
issues.previous=Попередній
issues.next=Далі
issues.open_title=Відкрити
issues.closed_title=Закриті
issues.close_issue=Закрити
issues.close_comment_issue=Прокоментувати і закрити
issues.reopen_issue=Відкрити знову
issues.reopen_comment_issue=Прокоментувати та відкрити знову
issues.create_comment=Коментар
issues.collaborator=Співавтор
issues.owner=Власник
issues.edit=Редагувати
issues.cancel=Відміна
issues.save=Зберегти
issues.label_title=Назва мітки
issues.label_color=Колір мітки
issues.label_count=%d міток
issues.label_open_issues=%d відкритих питань
issues.label_edit=Редагувати
issues.label_delete=Видалити
issues.label.filter_sort.alphabetically=За абеткою
issues.label.filter_sort.reverse_alphabetically=Зворотною абеткою
issues.label.filter_sort.by_size=Розмір
issues.label.filter_sort.reverse_by_size=Зворотний розмір
issues.subscribe=Підписатися
issues.unsubscribe=Відписатися
issues.start_tracking_short=Запустити
issues.start_tracking=Почати відстеження часу
issues.stop_tracking=Стоп
issues.add_time_cancel=Відміна
issues.cancel_tracking=Відміна
pulls.new=Новий запит на злиття
pulls.create=Створити запит на злиття
pulls.merge_pull_request=Об'єднати запит на злиття
milestones.new=Новий етап
milestones.open=Відкрити
milestones.close=Закрити
milestones.new_subheader=Створити етап для організації обговорень.
milestones.create=Створити етап
milestones.title=Заголовок
milestones.desc=Опис
milestones.due_date=Дата завершення (опціонально)
milestones.clear=Очистити
milestones.edit=Редагувати етап
milestones.cancel=Відміна
milestones.modify=Змінити етап
milestones.deletion=Видалення етапу
wiki=Wiki
wiki.page=Сторінка
wiki.filter_page=Фільтр сторінок
wiki.new_page=Створити нову сторінку
activity.merged_prs_count_1=Об'єднати запит на злиття
activity.merged_prs_count_n=Об'єднати запити на злиття
activity.closed_issue_label=Закриті
activity.new_issues_count_1=Нове обговорення
activity.new_issues_count_n=Нове обговорення
activity.new_issue_label=Відкриті
activity.unresolved_conv_label=Відкрити
activity.published_release_label=Опубліковано
search=Пошук
search.search_repo=Пошук репозиторію
settings=Параметри
settings.options=Параметри
settings.collaboration=Співпраця
settings.collaboration.admin=Адміністратор
settings.collaboration.write=Написати
settings.collaboration.read=Читати
settings.basic_settings=Базові налаштування
settings.mirror_settings=Налаштування дзеркала
settings.tracker_issue_style.numeric=Цифровий
settings.tracker_issue_style.alphanumeric=Буквено-цифровий
settings.danger_zone=Небезпечна зона
settings.transfer_owner=Новий власник
settings.confirm_delete=Підтвердження видалення
settings.add_collaborator=Додати нового співавтора
settings.delete_collaborator=Видалити
settings.collaborator_deletion=Видалення співавтора
settings.search_user_placeholder=Пошук користувача...
settings.org_not_allowed_to_be_collaborator=Організації не можуть бути додані як співавтори.
settings.user_is_org_member=Користувач входить в організацію, член якої не може бути доданий як співавтор.
settings.slack_color=Колір
settings.event_create=Створити
settings.event_create_desc=Гілку або тег створено
settings.event_pull_request=Запити до злиття
settings.event_pull_request_desc=Запит до злиття відкрито, закрито, перевідкрито, змінено, призначено, знято, мітку оновлено, мітку прибрано або синхронізовано.
settings.event_repository=Репозиторій
settings.event_repository_desc=Репозиторій створений або видалено
settings.active=Активний
release.cancel=Відміна
[org]
teams.add_team_repository=Додати репозиторій команди
[admin]
[action]
[tool]
[dropzone]
[notification]
[gpg]
[units]

View File

@@ -1,4 +1,4 @@
app_desc=基于 Go 语言的自助 Git 服务
app_desc=一款极易搭建的自助 Git 服务
home=首页
dashboard=控制面板
@@ -63,6 +63,7 @@ cancel=取消
install=安装页面
title=初始配置
docker_helper=如果您正在使用 Docker 容器运行 Gitea请务必先仔细阅读 <a target="_blank" rel="noopener" href="%s">官方文档</a> 后再对本页面进行填写。
requite_db_desc=Gitea 要求安装 MySQL、MSSQL、PostgreSQL、SQLite3 或 TiDB。
db_title=数据库设置
db_type=数据库类型
host=数据库主机
@@ -269,6 +270,7 @@ openid_been_used=OpenID 地址 '%s' 已被使用。
username_password_incorrect=用户名或密码错误
enterred_invalid_repo_name=请检查您输入的仓库名称是正确。
enterred_invalid_owner_name=请检查您输入的新所有者用户名是否正确。
enterred_invalid_password=请检查您输入的密码是否正确。
user_not_exist=该用户名不存在
last_org_owner=被移除用户为最后一位管理员。请添加一位新的管理员再进行移除成员操作!
cannot_add_org_to_team=组织不能被加入到团队中。
@@ -399,6 +401,8 @@ valid_until=有效期至
valid_forever=永久有效
last_used=上次使用在
no_activity=没有最近活动
can_read_info=读取
can_write_info=写入
key_state_desc=7 天内使用过该密钥
token_state_desc=7 天内使用过该密钥
show_openid=在个人信息上显示
@@ -753,7 +757,12 @@ pulls.is_checking=该合并请求正在进行冲突检查,请稍后再刷新
pulls.can_auto_merge_desc=该合并请求可以进行自动合并操作。
pulls.cannot_auto_merge_desc=该合并请求存在冲突,无法进行自动合并操作。
pulls.cannot_auto_merge_helper=请手动拉取代码变更以解决冲突。
pulls.no_merge_desc=由于未启用合并选项,此合并请求无法被合并。
pulls.no_merge_helper=要合并该请求,请在仓库设置中开启至少一个合并选项,或者手动合并该请求。
pulls.merge_pull_request=合并请求
pulls.rebase_merge_pull_request=变基并合并
pulls.squash_merge_pull_request=压缩提交并合并
pulls.invalid_merge_option=该合并选项不能被用于此合并请求
pulls.open_unmerged_pull_exists=`由于已经存在来自相同仓库和合并信息的未合并请求(#%d您无法执行重新开启操作。`
milestones.new=新的里程碑
@@ -892,6 +901,10 @@ settings.tracker_url_format_desc=您可以使用 <code>{user} {repo} {index}</co
settings.enable_timetracker=启用时间跟踪
settings.allow_only_contributors_to_track_time=只允许参与者跟踪时间
settings.pulls_desc=启用合并请求以接受社区贡献
settings.pulls.ignore_whitespace=检查冲突时忽略空白字符变更
settings.pulls.allow_merge_commits=允许合并提交
settings.pulls.allow_rebase_merge=允许变基到合并提交
settings.pulls.allow_squash_commits=允许在合并前压缩提交
settings.danger_zone=危险操作区
settings.new_owner_has_same_repo=新的仓库拥有者已经存在同名仓库!
settings.convert=转换为普通仓库
@@ -984,6 +997,8 @@ settings.add_dingtalk_hook_desc=为您的仓库增加 <a href="%s">钉钉</a>
settings.deploy_keys=管理部署密钥
settings.add_deploy_key=添加部署密钥
settings.deploy_key_desc=部署密钥仅具有只读权限,它在功能上和个人用户的公开密钥有本质区别。
settings.is_writable=允许写入权限
settings.is_writable_info=此密钥是否可以用于<strong>推送</strong>到此仓库?部署密钥始终具有”拉取“访问权限。
settings.no_deploy_keys=您还没有添加任何部署密钥。
settings.title=标题
settings.deploy_key_content=密钥文本
@@ -1308,6 +1323,7 @@ auths.attribute_mail=邮箱属性
auths.attributes_in_bind=从 Bind DN 中拉取属性信息
auths.filter=用户过滤规则
auths.admin_filter=管理员过滤规则
auths.ms_ad_sa=MS AD 搜索属性
auths.smtp_auth=SMTP 认证类型
auths.smtphost=SMTP 主机地址
auths.smtpport=SMTP 主机端口

View File

@@ -62,7 +62,8 @@ cancel=取消
[install]
install=安裝頁面
title=初始設定
docker_helper=如果您正在使用 Docker 容器運行 Gitea請務必先仔細閱讀 <a target="_blank" rel="noopener" href="%s">官方文</a> 後再對本頁面進行填寫。
docker_helper=如果您正在使用 Docker 容器運行 Gitea請務必先仔細閱讀<a target="_blank" rel="noopener" href="%s">官方文</a>後再對本頁面進行填寫。
requite_db_desc=Gitea 需要安裝 MySQL、MSSQL、PostgreSQL、SQLite3 或 TiDB 其中一項。
db_title=資料庫設定
db_type=資料庫類型
host=主機
@@ -269,6 +270,7 @@ openid_been_used=OpenID 位址 '%s' 已被使用。
username_password_incorrect=帳戶名稱或密碼有誤
enterred_invalid_repo_name=請檢查您輸入的儲存庫名稱是否正確。
enterred_invalid_owner_name=請檢查您輸入的擁有者名稱是否正確。
enterred_invalid_password=請檢查您輸入的密碼是否正確。
user_not_exist=該用戶名不存在
last_org_owner=無法移除群組內唯一的管理員
cannot_add_org_to_team=組織不能被新增為團隊成員。
@@ -398,6 +400,8 @@ valid_until=有效期至
valid_forever=永遠有效
last_used=上次使用在
no_activity=沒有最近活動
can_read_info=讀取
can_write_info=寫入
key_state_desc=該金鑰在 7 天內被使用過
token_state_desc=此 token 在過去七天內曾經被使用過
show_openid=在設定檔顯示
@@ -459,7 +463,7 @@ owner=擁有者
repo_name=儲存庫名稱
repo_name_helper=好的儲存庫名稱通常是簡短的、好記的、且獨特的。
visibility=可見度
visiblity_helper=該儲存庫為 <span class="ui red text">私有的</span>
visiblity_helper=該儲存庫為<span class="ui red text">私有的</span>
visiblity_helper_forced=網站管理員已強制要求所有新建儲存庫必須為 <span class="ui red text">私有儲存庫</span>
visiblity_fork_helper=(修改該值將會影響到所有複製儲存庫)
clone_helper=不知道如何操作?訪問 <a target="_blank" rel="noopener"href="%s"> 帮助説明</a>
@@ -478,14 +482,15 @@ create_repo=建立儲存庫
default_branch=默認分支
mirror_prune=裁減
mirror_prune_desc=刪除任何已不存在於遠端資料庫的遠端追蹤引用
mirror_interval=鏡像間隔 (有效時間單位為"h", "m""s")
mirror_interval=鏡像間隔 (有效時間單位為 "h", "m", "s")
mirror_interval_invalid=鏡像周期無效
mirror_address=鏡像地址
mirror_address_desc=請在此位址中引入任何必要使用者憑證。
mirror_last_synced=上次同步
mirror_last_synced=上次同步時間
watchers=關注者
stargazers=稱讚者
forks=複製儲存庫
pick_reaction=選擇你的表情反應
form.reach_limit_of_creation=您已經達到了儲存庫 %d 的上限。
form.name_reserved=儲存庫名稱 '%s' 是預留的。
@@ -493,7 +498,7 @@ form.name_pattern_not_allowed=儲存庫名稱格式不允許為'%s'。
need_auth=需要授權驗證
migrate_type=遷移類型
migrate_type_helper=該儲存庫將是一個 <span class="text blue">鏡像</span>
migrate_type_helper=該儲存庫將是一個<span class="text blue">鏡像</span>
migrate_repo=遷移儲存庫
migrate.clone_address=複製地址
migrate.clone_address_desc=該地址可以是 HTTP/HTTPS/GIT URL 或本地伺服器路徑。
@@ -536,6 +541,7 @@ pulls=合併請求
labels=標籤
milestones=里程碑
commits=提交歷史
commit=提交
releases=版本發佈
file_raw=原始文件
file_history=歷史記錄
@@ -625,6 +631,8 @@ issues.label_templates.info=沒有任何標籤。你可以點選上面建立一
issues.label_templates.helper=選擇一個標籤集
issues.label_templates.use=使用此標籤集
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.remove_label_at=刪除了 <div class="ui label" style="color: %s\; background-color: %s">%s</div> 標籤 %s
issues.add_milestone_at=`新增至<b>%s</b> 里程碑 %s`
issues.change_milestone_at=`%[3]s 修改了里程碑 <b>%[1]s</b> 到 <b>%[2]s</b>`
issues.remove_milestone_at=`從里程碑 %[2]s 刪除 <b>%[1]s</b>`
@@ -699,15 +707,29 @@ issues.label_deletion_success=此標籤已成功刪除。
issues.label.filter_sort.alphabetically=按字母顺序排序
issues.label.filter_sort.reverse_alphabetically=按字母反向排序
issues.label.filter_sort.by_size=大小
issues.label.filter_sort.reverse_by_size=大到小
issues.label.filter_sort.reverse_by_size=大到小
issues.num_participants=%d 參與者
issues.attachment.open_tab=`在新的標籤頁中查看 '%s'`
issues.attachment.download=`點擊下載 '%s'`
issues.subscribe=訂閱
issues.unsubscribe=取消訂閱
issues.tracker=時間追蹤
issues.start_tracking_short=開始
issues.start_tracking=開始追蹤時間
issues.start_tracking_history=`開始工作 %s`
issues.tracking_already_started=`您已經開始時間追蹤這個 <a href="%s">問題</a>!`
issues.stop_tracking=停止
issues.stop_tracking_history=`結束工作 %s`
issues.add_time=手動加入時間
issues.add_time_short=加入
issues.add_time_cancel=取消
issues.add_time_history=`加入了花費時間 %s`
issues.add_time_hours=小時
issues.add_time_minutes=分鐘
issues.add_time_sum_to_small=沒有輸入時間
issues.cancel_tracking=取消
issues.cancel_tracking_history=`取消時間追蹤 %s`
issues.time_spent_total=總共花費時間
pulls.desc=Pulls 管理你的程式碼審核及程式碼合併要求。
pulls.new=建立合併請求
@@ -724,7 +746,7 @@ pulls.title_desc=請求將 %[1]d 次程式碼提交從 <code>%[2]s</code> 合併
pulls.merged_title_desc=於 %[4]s 將 %[1]d 次代碼提交從 <code>%[2]s</code>合併至 <code>%[3]s</code>
pulls.tab_conversation=對話內容
pulls.tab_commits=程式碼提交
pulls.tab_files=文件變動
pulls.tab_files=檔案變動
pulls.reopen_to_merge=請重新開啟合併請求來完成合併操作。
pulls.merged=已合併
pulls.has_merged=此合併請求已成功合併。
@@ -734,6 +756,8 @@ pulls.can_auto_merge_desc=這個拉請求可以自動合併。
pulls.cannot_auto_merge_desc=此合併請求無法自動合併因發生衝突。
pulls.cannot_auto_merge_helper=請手動合併來解決衝突。
pulls.merge_pull_request=合併請求
pulls.rebase_merge_pull_request=Rebase 合併
pulls.squash_merge_pull_request=Squash 合併
pulls.open_unmerged_pull_exists=`您無法執行重新開啟的操作因為已有來自同儲存庫的未合併請求(#%d),該請求具相同資訊且等待合併中。`
milestones.new=新的里程碑
@@ -771,7 +795,7 @@ ext_wiki.desc=外部 Wiki 的連結
wiki=Wiki
wiki.welcome=歡迎來到專案 Wiki 頁面
wiki.welcome_desc=Wiki 是用於共同協作文的地方,清晰的文可以幫助其他人深入了解您的項目。
wiki.welcome_desc=Wiki 是用於共同協作文的地方,清晰的文可以幫助其他人深入了解您的項目。
wiki.desc=Wiki 是存放文件的地方
wiki.create_first_page=建立第一個頁面
wiki.page=頁面
@@ -788,15 +812,40 @@ wiki.page_already_exists=相同名稱的 Wiki 頁面已經存在。
wiki.pages=所有頁面
wiki.last_updated=最後更新於 %s
activity=活動
activity.period.filter_label=期間:
activity.period.daily=1 天
activity.period.halfweekly=3 天
activity.period.weekly=1 星期
activity.period.monthly=1 個月
activity.overview=概覽
activity.merged_prs_count_1=合併請求
activity.merged_prs_count_n=合併請求
activity.opened_prs_count_1=建立合併請求
activity.title.user_1=%d 使用者
activity.title.user_n=%d 使用者
activity.title.prs_1=%d 合併請求
activity.title.prs_n=%d 合併請求
activity.merged_prs_label=已合併
activity.closed_issues_count_1=已關閉的 Issue
activity.closed_issues_count_n=已關閉的 Issue
activity.title.issues_1=%d Issue
activity.title.issues_n=%d Issues
activity.title.issues_closed_by=%[2]s 關閉了 %[1]s
activity.title.issues_created_by=%[2]s 建立了 %[1]s
activity.closed_issue_label=已關閉
activity.new_issues_count_1=建立問題
activity.new_issues_count_n=建立問題
activity.new_issue_label=已開啟
activity.unresolved_conv_label=打開
activity.title.releases_1=%d 版本發佈
activity.title.releases_n=%d 版本發佈
activity.title.releases_published_by=%s 由 %s 發佈
activity.published_release_label=已發佈
search=搜尋
search.search_repo=搜尋儲存庫
search.results=在 <a href="%s"> %s </a> 中搜尋 "%s" 的结果
settings=儲存庫設定
settings.desc=設定是您可以管理儲存庫設定的地方
@@ -835,6 +884,7 @@ settings.tracker_url_format_desc=您可以使用 <code>{user} {repo} {index}</co
settings.enable_timetracker=啟用時間追蹤
settings.allow_only_contributors_to_track_time=僅允許貢獻者追蹤時間
settings.pulls_desc=啟用合併請求以接受社區貢獻
settings.pulls.allow_merge_commits=允許合併提交
settings.danger_zone=危險操作區
settings.new_owner_has_same_repo=新的儲存庫擁有者已經存在同名儲存庫!
settings.convert=轉換為正規儲存庫
@@ -871,7 +921,7 @@ settings.search_user_placeholder=搜尋用戶...
settings.org_not_allowed_to_be_collaborator=組織不允許被加為協同者。
settings.user_is_org_member=被操作的用戶是組織成員,因此無法新增為協作者!
settings.add_webhook=建立 Webhook
settings.hooks_desc=Webhook 允許您設定在 Gitea 上發生指定事件時對指定 URL 發送 POST 通知。查看 <a target="_blank" rel="noopener" href="%s">Webhooks 文</a> 獲取更多訊息。
settings.hooks_desc=Webhook 允許您設定在 Gitea 上發生指定事件時對指定 URL 發送 POST 通知。查看<a target="_blank" rel="noopener" href="%s">Webhooks 文</a>獲取更多訊息。
settings.webhook_deletion=刪除 Webhook
settings.webhook_deletion_desc=刪除該 Webhook 將會刪除與其有關的訊息和推送歷史。是否繼續?
settings.webhook_deletion_success=Webhook 刪除成功!
@@ -924,6 +974,8 @@ settings.slack_channel=頻道
settings.deploy_keys=管理部署金鑰
settings.add_deploy_key=新增部署金鑰
settings.deploy_key_desc=部署金鑰僅具有讀取權限,它在功能上和個人用戶的公開金鑰有本質區別。
settings.is_writable=允許寫入權限
settings.is_writable_info=此金鑰是否可以用於<strong>推送</strong>到此倉庫?部署金鑰始終具有讀取權限
settings.no_deploy_keys=您還沒有新增任何部署金鑰。
settings.title=標題
settings.deploy_key_content=金鑰文本
@@ -938,11 +990,18 @@ settings.protected_branch=分支保護
settings.protected_branch_can_push=允許推送?
settings.protected_branch_can_push_yes=你可以推送
settings.protected_branch_can_push_no=你不能推送
settings.branch_protection=<b>%s</b> 的分支保護
settings.protect_this_branch=保護此分支
settings.protect_this_branch_desc=禁止強制推送和刪除分支
settings.protect_whitelist_committers=允許推送到此分支的白名單
settings.protect_whitelist_committers_desc=新增用戶到此分支的白名單內,白名單用戶不受到推送限制
settings.protect_whitelist_users=允許推送到此分支的用戶
settings.protect_whitelist_search_users=搜尋使用者
settings.protect_whitelist_teams=團隊成員可以推送到此分支
settings.protect_whitelist_search_teams=搜尋團隊
settings.add_protected_branch=啟用保護
settings.delete_protected_branch=停用保護
settings.update_protect_branch_success=分支 %s 保護設定修改成功
settings.remove_protected_branch_success=%s 解鎖成功
settings.protected_branch_deletion=刪除一個受保護的分支
settings.protected_branch_deletion_desc=任何具有寫入權限的使用者都可以直接推進這個分支,您確定嗎?
@@ -957,7 +1016,7 @@ diff.data_not_available=沒有內容比較可以使用
diff.show_diff_stats=顯示文件統計
diff.show_split_view=分割檢視
diff.show_unified_view=統一視圖
diff.stats_desc=共有 <strong> %d 個文件被更改</strong>,包括 <strong>%d 次插入</strong> 和 <strong>%d 删除</strong>
diff.stats_desc=共有 <strong> %d 個檔案被更改</strong>,包括 <strong>%d 行新增</strong> 和 <strong>%d 删除</strong>
diff.bin=二進制
diff.view_file=查看文件
diff.file_suppressed=文件差異過大導致無法顯示
@@ -996,17 +1055,24 @@ release.tag_name_already_exist=已經存在使用相同標籤的發佈版本。
release.tag_name_invalid=標記名稱不是有效的。
release.downloads=下載附件
branch.name=分支名稱
branch.search=搜尋分支
branch.already_exists=分支名稱%s已經存在
branch.delete_head=刪除
branch.delete=刪除分支 %s
branch.delete_html=刪除分支
branch.delete_desc=刪除分支將是永久的。沒有其它方法能復原。
branch.delete_notices_1=- 此操作<strong>不可以</strong>被還原。
branch.delete_notices_2=- 此操作將永久刪除在 %s 分支內的所有內容。
branch.delete_notices_html=- 此操作會永久刪除 %s 分支所有資料
branch.deletion_success=%s 已被刪除。
branch.deletion_failed=刪除分支 %s 失敗。
branch.delete_branch_has_new_commits=不能刪除 %s因為合併後已新增了新的提交。
branch.create_branch=建立分支 <strong>%s</strong>
branch.create_success=成功建立 '%s' 分支!
branch.branch_already_exists=分支 '%s' 已存在此儲存庫
branch.deleted_by=刪除人: %s
branch.restore_success=%s 成功恢復
branch.restore_failed=還原分支 %s 失敗
branch.protected_deletion_failed=不可能刪除已受保護的分支 %s。
@@ -1203,7 +1269,7 @@ repos.private=私有庫
repos.watches=關註數
repos.stars=讚好數
repos.issues=問題數
repos.size=
repos.size=由小到
auths.auth_manage_panel=認證管理
auths.new=新增認證來源
@@ -1231,6 +1297,7 @@ auths.attribute_mail=電子郵箱屬性
auths.attributes_in_bind=從 Bind DN 中獲取屬性訊息
auths.filter=使用者篩選器
auths.admin_filter=管理者篩選器
auths.ms_ad_sa=MS AD 搜尋屬性
auths.smtp_auth=SMTP 驗證類型
auths.smtphost=SMTP 主機地址
auths.smtpport=SMTP 主機端口
@@ -1327,6 +1394,8 @@ config.active_code_lives=啟用用戶連結有效期
config.reset_password_code_lives=重設密碼代碼過期時間
config.default_keep_email_private=隱藏郵件地址的預設值
config.default_allow_create_organization=建立組織的預設權限
config.default_enable_timetracking=預設啟用時間追蹤
config.default_allow_only_contributors_to_track_time=僅允許貢獻者追蹤時間
config.no_reply_address=不可回復的郵件地址
config.webhook_config=Webhook 設定
@@ -1463,6 +1532,7 @@ no_read=您沒有任何已讀訊息。
pin=固定通知
mark_as_read=標記為已讀
mark_as_unread=標記為未讀
mark_all_as_read=標記所有為已讀
[gpg]
error.extract_sign=無法提取簽署

View File

@@ -957,37 +957,21 @@ func CleanUpPullRequest(ctx *context.Context) {
}
// Check if branch has no new commits
if len(pr.MergedCommitID) > 0 {
branchCommitID, err := gitRepo.GetBranchCommitID(pr.HeadBranch)
if err != nil {
log.Error(4, "GetBranchCommitID: %v", err)
ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", fullBranchName))
return
}
commit, err := gitBaseRepo.GetCommit(pr.MergedCommitID)
if err != nil {
log.Error(4, "GetCommit: %v", err)
ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", fullBranchName))
return
}
isParent := false
for i := 0; i < commit.ParentCount(); i++ {
if parent, err := commit.Parent(i); err != nil {
log.Error(4, "Parent: %v", err)
ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", fullBranchName))
return
} else if parent.ID.String() == branchCommitID {
isParent = true
break
}
}
if !isParent {
ctx.Flash.Error(ctx.Tr("repo.branch.delete_branch_has_new_commits", fullBranchName))
return
}
headCommitID, err := gitBaseRepo.GetRefCommitID(pr.GetGitRefName())
if err != nil {
log.Error(4, "GetRefCommitID: %v", err)
ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", fullBranchName))
return
}
branchCommitID, err := gitRepo.GetBranchCommitID(pr.HeadBranch)
if err != nil {
log.Error(4, "GetBranchCommitID: %v", err)
ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", fullBranchName))
return
}
if headCommitID != branchCommitID {
ctx.Flash.Error(ctx.Tr("repo.branch.delete_branch_has_new_commits", fullBranchName))
return
}
if err := gitRepo.DeleteBranch(pr.HeadBranch, git.DeleteBranchOptions{

View File

@@ -13,27 +13,27 @@
</div>
{{range .Emails}}
<div class="item">
{{if not .IsPrimary}}
<div class="right floated content">
<button class="ui red tiny button delete-button" data-url="{{$.Link}}/delete" data-id="{{.ID}}">
{{$.i18n.Tr "settings.delete_key"}}
</button>
</div>
{{if .IsActivated}}
<div class="right floated content">
<form action="{{$.Link}}" method="post">
{{$.CsrfTokenHtml}}
<input name="_method" type="hidden" value="PRIMARY">
<input name="id" type="hidden" value="{{.ID}}">
<button class="ui blue tiny button">{{$.i18n.Tr "settings.primary_email"}}</button>
</form>
</div>
{{end}}
{{end}}
<div class="content">
<strong>{{.Email}}</strong>
{{if .IsPrimary}}<span class="text red">{{$.i18n.Tr "settings.primary"}}</span>{{end}}
{{if not .IsPrimary}}
<div class="right floated content">
<button class="ui red tiny button delete-button" data-url="{{$.Link}}/delete" data-id="{{.ID}}">
{{$.i18n.Tr "settings.delete_email"}}
</button>
</div>
{{if .IsActivated}}
<div class="right floated content">
<form action="{{$.Link}}" method="post">
{{$.CsrfTokenHtml}}
<input name="_method" type="hidden" value="PRIMARY">
<input name="id" type="hidden" value="{{.ID}}">
<button class="ui blue tiny button">{{$.i18n.Tr "settings.primary_email"}}</button>
</form>
</div>
{{end}}
{{end}}
<div class="content">
<strong>{{.Email}}</strong>
{{if .IsPrimary}}<span class="text red">{{$.i18n.Tr "settings.primary"}}</span>{{end}}
</div>
</div>
{{end}}
</div>

View File

@@ -45,6 +45,10 @@ func (b *Builder) selectWriteTo(w Writer) error {
}
}
if !b.cond.IsValid() {
return nil
}
if _, err := fmt.Fprint(w, " WHERE "); err != nil {
return err
}

View File

@@ -25,7 +25,9 @@ func And(conds ...Cond) Cond {
func (and condAnd) WriteTo(w Writer) error {
for i, cond := range and {
_, isOr := cond.(condOr)
if isOr {
_, isExpr := cond.(expr)
wrap := isOr || isExpr
if wrap {
fmt.Fprint(w, "(")
}
@@ -34,7 +36,7 @@ func (and condAnd) WriteTo(w Writer) error {
return err
}
if isOr {
if wrap {
fmt.Fprint(w, ")")
}

View File

@@ -1,11 +1,12 @@
package core
import (
"errors"
"fmt"
"time"
"bytes"
"encoding/gob"
"errors"
"fmt"
"strings"
"time"
)
const (
@@ -55,11 +56,10 @@ func encodeIds(ids []PK) (string, error) {
return buf.String(), err
}
func decodeIds(s string) ([]PK, error) {
pks := make([]PK, 0)
dec := gob.NewDecoder(bytes.NewBufferString(s))
dec := gob.NewDecoder(strings.NewReader(s))
err := dec.Decode(&pks)
return pks, err

View File

@@ -11,4 +11,5 @@ database:
test:
override:
# './...' is a relative pattern which means all subdirectories
- go test -v -race
- go test -v -race
- go test -v -race --dbtype=sqlite3

View File

@@ -79,6 +79,10 @@ func (col *Column) String(d Dialect) string {
}
}
if col.Default != "" {
sql += "DEFAULT " + col.Default + " "
}
if d.ShowCreateNull() {
if col.Nullable {
sql += "NULL "
@@ -87,10 +91,6 @@ func (col *Column) String(d Dialect) string {
}
}
if col.Default != "" {
sql += "DEFAULT " + col.Default + " "
}
return sql
}
@@ -99,6 +99,10 @@ func (col *Column) StringNoPk(d Dialect) string {
sql += d.SqlType(col) + " "
if col.Default != "" {
sql += "DEFAULT " + col.Default + " "
}
if d.ShowCreateNull() {
if col.Nullable {
sql += "NULL "
@@ -107,10 +111,6 @@ func (col *Column) StringNoPk(d Dialect) string {
}
}
if col.Default != "" {
sql += "DEFAULT " + col.Default + " "
}
return sql
}

View File

@@ -44,6 +44,9 @@ func convertTime(dest *NullTime, src interface{}) error {
}
*dest = NullTime(t)
return nil
case time.Time:
*dest = NullTime(s)
return nil
case nil:
default:
return fmt.Errorf("unsupported driver -> Scan pair: %T -> %T", src, dest)

View File

@@ -32,13 +32,10 @@ proposed functionality.
We appreciate any bug reports, but especially ones with self-contained
(doesn't depend on code outside of xorm), minimal (can't be simplified
further) test cases. It's especially helpful if you can submit a pull
request with just the failing test case (you'll probably want to
pattern it after the tests in
[base.go](https://github.com/go-xorm/tests/blob/master/base.go) AND
[benchmark.go](https://github.com/go-xorm/tests/blob/master/benchmark.go).
request with just the failing test case(you can find some example test file like [session_get_test.go](https://github.com/go-xorm/xorm/blob/master/session_get_test.go)).
If you implements a new database interface, you maybe need to add a <databasename>_test.go file.
For example, [mysql_test.go](https://github.com/go-xorm/tests/blob/master/mysql/mysql_test.go)
If you implements a new database interface, you maybe need to add a test_<databasename>.sh file.
For example, [mysql_test.go](https://github.com/go-xorm/xorm/blob/master/test_mysql.sh)
### New functionality

View File

@@ -28,6 +28,8 @@ Xorm is a simple and powerful ORM for Go.
* SQL Builder support via [github.com/go-xorm/builder](https://github.com/go-xorm/builder)
* Automatical Read/Write seperatelly
# Drivers Support
Drivers for Go's sql package which currently support database/sql includes:
@@ -48,6 +50,13 @@ Drivers for Go's sql package which currently support database/sql includes:
# Changelog
* **v0.6.4**
* Automatical Read/Write seperatelly
* Query/QueryString/QueryInterface and action with Where/And
* Get support non-struct variables
* BufferSize on Iterate
* fix some other bugs.
* **v0.6.3**
* merge tests to main project
* add `Exist` function
@@ -61,13 +70,6 @@ Drivers for Go's sql package which currently support database/sql includes:
* add Scan features to Get
* add QueryString method
* **v0.6.0**
* remove support for ql
* add query condition builder support via [github.com/go-xorm/builder](https://github.com/go-xorm/builder), so `Where`, `And`, `Or`
methods can use `builder.Cond` as parameter
* add Sum, SumInt, SumInt64 and NotIn methods
* some bugs fixed
[More changes ...](https://github.com/go-xorm/manual-en-US/tree/master/chapter-16)
# Installation
@@ -106,15 +108,36 @@ type User struct {
err := engine.Sync2(new(User))
```
* `Query` runs a SQL string, the returned results is `[]map[string][]byte`, `QueryString` returns `[]map[string]string`.
* Create Engine Group
```Go
dataSourceNameSlice := []string{masterDataSourceName, slave1DataSourceName, slave2DataSourceName}
engineGroup, err := xorm.NewEngineGroup(driverName, dataSourceNameSlice)
```
```Go
masterEngine, err := xorm.NewEngine(driverName, masterDataSourceName)
slave1Engine, err := xorm.NewEngine(driverName, slave1DataSourceName)
slave2Engine, err := xorm.NewEngine(driverName, slave2DataSourceName)
engineGroup, err := xorm.NewEngineGroup(masterEngine, []*Engine{slave1Engine, slave2Engine})
```
Then all place where `engine` you can just use `engineGroup`.
* `Query` runs a SQL string, the returned results is `[]map[string][]byte`, `QueryString` returns `[]map[string]string`, `QueryInterface` returns `[]map[string]interface{}`.
```Go
results, err := engine.Query("select * from user")
results, err := engine.Where("a = 1").Query()
results, err := engine.QueryString("select * from user")
results, err := engine.Where("a = 1").QueryString()
results, err := engine.QueryInterface("select * from user")
results, err := engine.Where("a = 1").QueryInterface()
```
* `Execute` runs a SQL string, it returns `affected` and `error`
* `Exec` runs a SQL string, it returns `affected` and `error`
```Go
affected, err := engine.Exec("update user set age = ? where name = ?", age, name)
@@ -125,62 +148,76 @@ affected, err := engine.Exec("update user set age = ? where name = ?", age, name
```Go
affected, err := engine.Insert(&user)
// INSERT INTO struct () values ()
affected, err := engine.Insert(&user1, &user2)
// INSERT INTO struct1 () values ()
// INSERT INTO struct2 () values ()
affected, err := engine.Insert(&users)
// INSERT INTO struct () values (),(),()
affected, err := engine.Insert(&user1, &users)
// INSERT INTO struct1 () values ()
// INSERT INTO struct2 () values (),(),()
```
* Query one record from database
* `Get` query one record from database
```Go
has, err := engine.Get(&user)
// SELECT * FROM user LIMIT 1
has, err := engine.Where("name = ?", name).Desc("id").Get(&user)
// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1
var name string
has, err := engine.Where("id = ?", id).Cols("name").Get(&name)
// SELECT name FROM user WHERE id = ?
var id int64
has, err := engine.Where("name = ?", name).Cols("id").Get(&id)
has, err := engine.SQL("select id from user").Get(&id)
// SELECT id FROM user WHERE name = ?
var valuesMap = make(map[string]string)
has, err := engine.Where("id = ?", id).Get(&valuesMap)
// SELECT * FROM user WHERE id = ?
var valuesSlice = make([]interface{}, len(cols))
has, err := engine.Where("id = ?", id).Cols(cols...).Get(&valuesSlice)
// SELECT col1, col2, col3 FROM user WHERE id = ?
```
* Check if one record exist on table
* `Exist` check if one record exist on table
```Go
has, err := testEngine.Exist(new(RecordExist))
// SELECT * FROM record_exist LIMIT 1
has, err = testEngine.Exist(&RecordExist{
Name: "test1",
})
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
has, err = testEngine.Where("name = ?", "test1").Exist(&RecordExist{})
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
has, err = testEngine.SQL("select * from record_exist where name = ?", "test1").Exist()
// select * from record_exist where name = ?
has, err = testEngine.Table("record_exist").Exist()
// SELECT * FROM record_exist LIMIT 1
has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist()
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
```
* Query multiple records from database, also you can use join and extends
* `Find` query multiple records from database, also you can use join and extends
```Go
var users []User
err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users)
// SELECT * FROM user WHERE name = ? AND age > 10 limit 0 offset 10
// SELECT * FROM user WHERE name = ? AND age > 10 limit 10 offset 0
type Detail struct {
Id int64
@@ -193,14 +230,14 @@ type UserDetail struct {
}
var users []UserDetail
err := engine.Table("user").Select("user.*, detail.*")
err := engine.Table("user").Select("user.*, detail.*").
Join("INNER", "detail", "detail.user_id = user.id").
Where("user.name = ?", name).Limit(10, 0).
Find(&users)
// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 0 offset 10
// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 10 offset 0
```
* Query multiple records and record by record handle, there are two methods Iterate and Rows
* `Iterate` and `Rows` query multiple records and record by record handle, there are two methods Iterate and Rows
```Go
err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
@@ -209,6 +246,13 @@ err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
})
// SELECT * FROM user
err := engine.BufferSize(100).Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
user := bean.(*User)
return nil
})
// SELECT * FROM user Limit 0, 100
// SELECT * FROM user Limit 101, 100
rows, err := engine.Rows(&User{Name:name})
// SELECT * FROM user
defer rows.Close()
@@ -218,7 +262,7 @@ for rows.Next() {
}
```
* Update one or more records, default will update non-empty and non-zero fields except when you use Cols, AllCols and so on.
* `Update` update one or more records, default will update non-empty and non-zero fields except when you use Cols, AllCols and so on.
```Go
affected, err := engine.Id(1).Update(&user)
@@ -243,21 +287,39 @@ affected, err := engine.Id(1).AllCols().Update(&user)
// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ?
```
* Delete one or more records, Delete MUST have condition
* `Delete` delete one or more records, Delete MUST have condition
```Go
affected, err := engine.Where(...).Delete(&user)
// DELETE FROM user Where ...
affected, err := engine.Id(2).Delete(&user)
affected, err := engine.ID(2).Delete(&user)
// DELETE FROM user Where id = ?
```
* Count records
* `Count` count records
```Go
counts, err := engine.Count(&user)
// SELECT count(*) AS total FROM user
```
* `Sum` sum functions
```Go
agesFloat64, err := engine.Sum(&user, "age")
// SELECT sum(age) AS total FROM user
agesInt64, err := engine.SumInt(&user, "age")
// SELECT sum(age) AS total FROM user
sumFloat64Slice, err := engine.Sums(&user, "age", "score")
// SELECT sum(age), sum(score) FROM user
sumInt64Slice, err := engine.SumsInt(&user, "age", "score")
// SELECT sum(age), sum(score) FROM user
```
* Query conditions builder
```Go
@@ -265,6 +327,59 @@ err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))
// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?)
```
* Multiple operations in one go routine, no transation here but resue session memory
```Go
session := engine.NewSession()
defer session.Close()
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
if _, err := session.Insert(&user1); err != nil {
return err
}
user2 := Userinfo{Username: "yyy"}
if _, err := session.Where("id = ?", 2).Update(&user2); err != nil {
return err
}
if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil {
return err
}
return nil
```
* Transation should on one go routine. There is transaction and resue session memory
```Go
session := engine.NewSession()
defer session.Close()
// add Begin() before any action
if err := session.Begin(); err != nil {
// if returned then will rollback automatically
return err
}
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
if _, err := session.Insert(&user1); err != nil {
return err
}
user2 := Userinfo{Username: "yyy"}
if _, err := session.Where("id = ?", 2).Update(&user2); err != nil {
return err
}
if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil {
return err
}
// add Commit() after all actions
return session.Commit()
```
# Cases
* [studygolang](http://studygolang.com/) - [github.com/studygolang/studygolang](https://github.com/studygolang/studygolang)

View File

@@ -115,12 +115,33 @@ type User struct {
err := engine.Sync2(new(User))
```
* `Query` 最原始的也支持SQL语句查询返回的结果类型为 []map[string][]byte。`QueryString` 返回 []map[string]string
* 创建Engine组
```Go
dataSourceNameSlice := []string{masterDataSourceName, slave1DataSourceName, slave2DataSourceName}
engineGroup, err := xorm.NewEngineGroup(driverName, dataSourceNameSlice)
```
```Go
masterEngine, err := xorm.NewEngine(driverName, masterDataSourceName)
slave1Engine, err := xorm.NewEngine(driverName, slave1DataSourceName)
slave2Engine, err := xorm.NewEngine(driverName, slave2DataSourceName)
engineGroup, err := xorm.NewEngineGroup(masterEngine, []*Engine{slave1Engine, slave2Engine})
```
所有使用 `engine` 都可以简单的用 `engineGroup` 来替换。
* `Query` 最原始的也支持SQL语句查询返回的结果类型为 []map[string][]byte。`QueryString` 返回 []map[string]string, `QueryInterface` 返回 `[]map[string]interface{}`.
```Go
results, err := engine.Query("select * from user")
results, err := engine.Where("a = 1").Query()
results, err := engine.QueryString("select * from user")
results, err := engine.Where("a = 1").QueryString()
results, err := engine.QueryInterface("select * from user")
results, err := engine.Where("a = 1").QueryInterface()
```
* `Exec` 执行一个SQL语句
@@ -129,67 +150,81 @@ results, err := engine.QueryString("select * from user")
affected, err := engine.Exec("update user set age = ? where name = ?", age, name)
```
* 插入一条或者多条记录
* `Insert` 插入一条或者多条记录
```Go
affected, err := engine.Insert(&user)
// INSERT INTO struct () values ()
affected, err := engine.Insert(&user1, &user2)
// INSERT INTO struct1 () values ()
// INSERT INTO struct2 () values ()
affected, err := engine.Insert(&users)
// INSERT INTO struct () values (),(),()
affected, err := engine.Insert(&user1, &users)
// INSERT INTO struct1 () values ()
// INSERT INTO struct2 () values (),(),()
```
* 查询单条记录
* `Get` 查询单条记录
```Go
has, err := engine.Get(&user)
// SELECT * FROM user LIMIT 1
has, err := engine.Where("name = ?", name).Desc("id").Get(&user)
// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1
var name string
has, err := engine.Where("id = ?", id).Cols("name").Get(&name)
// SELECT name FROM user WHERE id = ?
var id int64
has, err := engine.Where("name = ?", name).Cols("id").Get(&id)
has, err := engine.SQL("select id from user").Get(&id)
// SELECT id FROM user WHERE name = ?
var valuesMap = make(map[string]string)
has, err := engine.Where("id = ?", id).Get(&valuesMap)
// SELECT * FROM user WHERE id = ?
var valuesSlice = make([]interface{}, len(cols))
has, err := engine.Where("id = ?", id).Cols(cols...).Get(&valuesSlice)
// SELECT col1, col2, col3 FROM user WHERE id = ?
```
* 检测记录是否存在
* `Exist` 检测记录是否存在
```Go
has, err := testEngine.Exist(new(RecordExist))
// SELECT * FROM record_exist LIMIT 1
has, err = testEngine.Exist(&RecordExist{
Name: "test1",
})
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
has, err = testEngine.Where("name = ?", "test1").Exist(&RecordExist{})
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
has, err = testEngine.SQL("select * from record_exist where name = ?", "test1").Exist()
// select * from record_exist where name = ?
has, err = testEngine.Table("record_exist").Exist()
// SELECT * FROM record_exist LIMIT 1
has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist()
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
```
* 查询多条记录当然可以使用Join和extends来组合使用
* `Find` 查询多条记录当然可以使用Join和extends来组合使用
```Go
var users []User
err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users)
// SELECT * FROM user WHERE name = ? AND age > 10 limit 0 offset 10
// SELECT * FROM user WHERE name = ? AND age > 10 limit 10 offset 0
type Detail struct {
Id int64
@@ -206,10 +241,10 @@ err := engine.Table("user").Select("user.*, detail.*")
Join("INNER", "detail", "detail.user_id = user.id").
Where("user.name = ?", name).Limit(10, 0).
Find(&users)
// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 0 offset 10
// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 10 offset 0
```
* 根据条件遍历数据库,可以有两种方式: Iterate and Rows
* `Iterate``Rows` 根据条件遍历数据库,可以有两种方式: Iterate and Rows
```Go
err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
@@ -218,6 +253,13 @@ err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
})
// SELECT * FROM user
err := engine.BufferSize(100).Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
user := bean.(*User)
return nil
})
// SELECT * FROM user Limit 0, 100
// SELECT * FROM user Limit 101, 100
rows, err := engine.Rows(&User{Name:name})
// SELECT * FROM user
defer rows.Close()
@@ -227,7 +269,7 @@ for rows.Next() {
}
```
* 更新数据除非使用Cols,AllCols函数指明默认只更新非空和非0的字段
* `Update` 更新数据除非使用Cols,AllCols函数指明默认只更新非空和非0的字段
```Go
affected, err := engine.Id(1).Update(&user)
@@ -252,20 +294,39 @@ affected, err := engine.Id(1).AllCols().Update(&user)
// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ?
```
* 删除记录需要注意删除必须至少有一个条件否则会报错。要清空数据库可以用EmptyTable
* `Delete` 删除记录需要注意删除必须至少有一个条件否则会报错。要清空数据库可以用EmptyTable
```Go
affected, err := engine.Where(...).Delete(&user)
// DELETE FROM user Where ...
affected, err := engine.ID(2).Delete(&user)
// DELETE FROM user Where id = ?
```
* 获取记录条数
* `Count` 获取记录条数
```Go
counts, err := engine.Count(&user)
// SELECT count(*) AS total FROM user
```
* `Sum` 求和函数
```Go
agesFloat64, err := engine.Sum(&user, "age")
// SELECT sum(age) AS total FROM user
agesInt64, err := engine.SumInt(&user, "age")
// SELECT sum(age) AS total FROM user
sumFloat64Slice, err := engine.Sums(&user, "age", "score")
// SELECT sum(age), sum(score) FROM user
sumInt64Slice, err := engine.SumsInt(&user, "age", "score")
// SELECT sum(age), sum(score) FROM user
```
* 条件编辑器
```Go
@@ -273,6 +334,59 @@ err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))
// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?)
```
* 在一个Go程中多次操作数据库但没有事务
```Go
session := engine.NewSession()
defer session.Close()
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
if _, err := session.Insert(&user1); err != nil {
return err
}
user2 := Userinfo{Username: "yyy"}
if _, err := session.Where("id = ?", 2).Update(&user2); err != nil {
return err
}
if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil {
return err
}
return nil
```
* 在一个Go程中有事务
```Go
session := engine.NewSession()
defer session.Close()
// add Begin() before any action
if err := session.Begin(); err != nil {
// if returned then will rollback automatically
return err
}
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
if _, err := session.Insert(&user1); err != nil {
return err
}
user2 := Userinfo{Username: "yyy"}
if _, err := session.Where("id = ?", 2).Update(&user2); err != nil {
return err
}
if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil {
return err
}
// add Commit() after all actions
return session.Commit()
```
# 案例
* [Go语言中文网](http://studygolang.com/) - [github.com/studygolang/studygolang](https://github.com/studygolang/studygolang)

26
vendor/github.com/go-xorm/xorm/context.go generated vendored Normal file
View File

@@ -0,0 +1,26 @@
// Copyright 2017 The Xorm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.8
package xorm
import "context"
// PingContext tests if database is alive
func (engine *Engine) PingContext(ctx context.Context) error {
session := engine.NewSession()
defer session.Close()
return session.PingContext(ctx)
}
// PingContext test if database is ok
func (session *Session) PingContext(ctx context.Context) error {
if session.isAutoClose {
defer session.Close()
}
session.engine.logger.Infof("PING DATABASE %v", session.engine.DriverName())
return session.DB().PingContext(ctx)
}

View File

@@ -209,10 +209,10 @@ func convertAssign(dest, src interface{}) error {
if src == nil {
dv.Set(reflect.Zero(dv.Type()))
return nil
} else {
dv.Set(reflect.New(dv.Type().Elem()))
return convertAssign(dv.Interface(), src)
}
dv.Set(reflect.New(dv.Type().Elem()))
return convertAssign(dv.Interface(), src)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
s := asString(src)
i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())

View File

@@ -8,7 +8,6 @@ import (
"errors"
"fmt"
"net/url"
"sort"
"strconv"
"strings"
@@ -765,13 +764,18 @@ var (
"YES": true,
"ZONE": true,
}
// DefaultPostgresSchema default postgres schema
DefaultPostgresSchema = "public"
)
type postgres struct {
core.Base
schema string
}
func (db *postgres) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error {
db.schema = DefaultPostgresSchema
return db.Base.Init(d, db, uri, drivername, dataSourceName)
}
@@ -923,7 +927,7 @@ func (db *postgres) IsColumnExist(tableName, colName string) (bool, error) {
func (db *postgres) GetColumns(tableName string) ([]string, map[string]*core.Column, error) {
// FIXME: the schema should be replaced by user custom's
args := []interface{}{tableName, "public"}
args := []interface{}{tableName, db.schema}
s := `SELECT column_name, column_default, is_nullable, data_type, character_maximum_length, numeric_precision, numeric_precision_radix ,
CASE WHEN p.contype = 'p' THEN true ELSE false END AS primarykey,
CASE WHEN p.contype = 'u' THEN true ELSE false END AS uniquekey
@@ -1024,8 +1028,7 @@ WHERE c.relkind = 'r'::char AND c.relname = $1 AND s.table_schema = $2 AND f.att
}
func (db *postgres) GetTables() ([]*core.Table, error) {
// FIXME: replace public to user customrize schema
args := []interface{}{"public"}
args := []interface{}{db.schema}
s := fmt.Sprintf("SELECT tablename FROM pg_tables WHERE schemaname = $1")
db.LogSQL(s, args)
@@ -1050,8 +1053,7 @@ func (db *postgres) GetTables() ([]*core.Table, error) {
}
func (db *postgres) GetIndexes(tableName string) (map[string]*core.Index, error) {
// FIXME: replace the public schema to user specify schema
args := []interface{}{"public", tableName}
args := []interface{}{db.schema, tableName}
s := fmt.Sprintf("SELECT indexname, indexdef FROM pg_indexes WHERE schemaname=$1 AND tablename=$2")
db.LogSQL(s, args)
@@ -1117,10 +1119,6 @@ func (vs values) Get(k string) (v string) {
return vs[k]
}
func errorf(s string, args ...interface{}) {
panic(fmt.Errorf("pq: %s", fmt.Sprintf(s, args...)))
}
func parseURL(connstr string) (string, error) {
u, err := url.Parse(connstr)
if err != nil {
@@ -1131,46 +1129,18 @@ func parseURL(connstr string) (string, error) {
return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme)
}
var kvs []string
escaper := strings.NewReplacer(` `, `\ `, `'`, `\'`, `\`, `\\`)
accrue := func(k, v string) {
if v != "" {
kvs = append(kvs, k+"="+escaper.Replace(v))
}
}
if u.User != nil {
v := u.User.Username()
accrue("user", v)
v, _ = u.User.Password()
accrue("password", v)
}
i := strings.Index(u.Host, ":")
if i < 0 {
accrue("host", u.Host)
} else {
accrue("host", u.Host[:i])
accrue("port", u.Host[i+1:])
}
if u.Path != "" {
accrue("dbname", u.Path[1:])
return escaper.Replace(u.Path[1:]), nil
}
q := u.Query()
for k := range q {
accrue(k, q.Get(k))
}
sort.Strings(kvs) // Makes testing easier (not a performance concern)
return strings.Join(kvs, " "), nil
return "", nil
}
func parseOpts(name string, o values) {
func parseOpts(name string, o values) error {
if len(name) == 0 {
return
return fmt.Errorf("invalid options: %s", name)
}
name = strings.TrimSpace(name)
@@ -1179,31 +1149,36 @@ func parseOpts(name string, o values) {
for _, p := range ps {
kv := strings.Split(p, "=")
if len(kv) < 2 {
errorf("invalid option: %q", p)
return fmt.Errorf("invalid option: %q", p)
}
o.Set(kv[0], kv[1])
}
return nil
}
func (p *pqDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
db := &core.Uri{DbType: core.POSTGRES}
o := make(values)
var err error
if strings.HasPrefix(dataSourceName, "postgresql://") || strings.HasPrefix(dataSourceName, "postgres://") {
dataSourceName, err = parseURL(dataSourceName)
db.DbName, err = parseURL(dataSourceName)
if err != nil {
return nil, err
}
} else {
o := make(values)
err = parseOpts(dataSourceName, o)
if err != nil {
return nil, err
}
}
parseOpts(dataSourceName, o)
db.DbName = o.Get("dbname")
db.DbName = o.Get("dbname")
}
if db.DbName == "" {
return nil, errors.New("dbname is empty")
}
/*db.Schema = o.Get("schema")
if len(db.Schema) == 0 {
db.Schema = "public"
}*/
return db, nil
}

View File

@@ -47,6 +47,23 @@ type Engine struct {
disableGlobalCache bool
tagHandlers map[string]tagHandler
engineGroup *EngineGroup
}
// BufferSize sets buffer size for iterate
func (engine *Engine) BufferSize(size int) *Session {
session := engine.NewSession()
session.isAutoClose = true
return session.BufferSize(size)
}
// CondDeleted returns the conditions whether a record is soft deleted.
func (engine *Engine) CondDeleted(colName string) builder.Cond {
if engine.dialect.DBType() == core.MSSQL {
return builder.IsNull{colName}
}
return builder.IsNull{colName}.Or(builder.Eq{colName: zeroTime1})
}
// ShowSQL show SQL statement or not on logger if log level is great than INFO
@@ -79,6 +96,11 @@ func (engine *Engine) SetLogger(logger core.ILogger) {
engine.dialect.SetLogger(logger)
}
// SetLogLevel sets the logger level
func (engine *Engine) SetLogLevel(level core.LogLevel) {
engine.logger.SetLevel(level)
}
// SetDisableGlobalCache disable global cache or not
func (engine *Engine) SetDisableGlobalCache(disable bool) {
if engine.disableGlobalCache != disable {
@@ -201,6 +223,11 @@ func (engine *Engine) SetDefaultCacher(cacher core.Cacher) {
engine.Cacher = cacher
}
// GetDefaultCacher returns the default cacher
func (engine *Engine) GetDefaultCacher() core.Cacher {
return engine.Cacher
}
// NoCache If you has set default cacher, and you want temporilly stop use cache,
// you can use NoCache()
func (engine *Engine) NoCache() *Session {
@@ -736,6 +763,13 @@ func (engine *Engine) OrderBy(order string) *Session {
return session.OrderBy(order)
}
// Prepare enables prepare statement
func (engine *Engine) Prepare() *Session {
session := engine.NewSession()
session.isAutoClose = true
return session.Prepare()
}
// Join the join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN
func (engine *Engine) Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *Session {
session := engine.NewSession()
@@ -757,7 +791,8 @@ func (engine *Engine) Having(conditions string) *Session {
return session.Having(conditions)
}
func (engine *Engine) unMapType(t reflect.Type) {
// UnMapType removes the datbase mapper of a type
func (engine *Engine) UnMapType(t reflect.Type) {
engine.mutex.Lock()
defer engine.mutex.Unlock()
delete(engine.Tables, t)
@@ -914,7 +949,7 @@ func (engine *Engine) mapType(v reflect.Value) (*core.Table, error) {
}
if pStart > -1 {
if !strings.HasSuffix(k, ")") {
return nil, errors.New("cannot match ) charactor")
return nil, fmt.Errorf("field %s tag %s cannot match ) charactor", col.FieldName, key)
}
ctx.tagName = k[:pStart]
@@ -1341,24 +1376,24 @@ func (engine *Engine) Exec(sql string, args ...interface{}) (sql.Result, error)
}
// Query a raw sql and return records as []map[string][]byte
func (engine *Engine) Query(sql string, paramStr ...interface{}) (resultsSlice []map[string][]byte, err error) {
func (engine *Engine) Query(sqlorArgs ...interface{}) (resultsSlice []map[string][]byte, err error) {
session := engine.NewSession()
defer session.Close()
return session.Query(sql, paramStr...)
return session.Query(sqlorArgs...)
}
// QueryString runs a raw sql and return records as []map[string]string
func (engine *Engine) QueryString(sqlStr string, args ...interface{}) ([]map[string]string, error) {
func (engine *Engine) QueryString(sqlorArgs ...interface{}) ([]map[string]string, error) {
session := engine.NewSession()
defer session.Close()
return session.QueryString(sqlStr, args...)
return session.QueryString(sqlorArgs...)
}
// QueryInterface runs a raw sql and return records as []map[string]interface{}
func (engine *Engine) QueryInterface(sqlStr string, args ...interface{}) ([]map[string]interface{}, error) {
func (engine *Engine) QueryInterface(sqlorArgs ...interface{}) ([]map[string]interface{}, error) {
session := engine.NewSession()
defer session.Close()
return session.QueryInterface(sqlStr, args...)
return session.QueryInterface(sqlorArgs...)
}
// Insert one or more records
@@ -1564,24 +1599,39 @@ func (engine *Engine) formatTime(sqlTypeName string, t time.Time) (v interface{}
return
}
// GetColumnMapper returns the column name mapper
func (engine *Engine) GetColumnMapper() core.IMapper {
return engine.ColumnMapper
}
// GetTableMapper returns the table name mapper
func (engine *Engine) GetTableMapper() core.IMapper {
return engine.TableMapper
}
// GetTZLocation returns time zone of the application
func (engine *Engine) GetTZLocation() *time.Location {
return engine.TZLocation
}
// SetTZLocation sets time zone of the application
func (engine *Engine) SetTZLocation(tz *time.Location) {
engine.TZLocation = tz
}
// GetTZDatabase returns time zone of the database
func (engine *Engine) GetTZDatabase() *time.Location {
return engine.DatabaseTZ
}
// SetTZDatabase sets time zone of the database
func (engine *Engine) SetTZDatabase(tz *time.Location) {
engine.DatabaseTZ = tz
}
// Unscoped always disable struct tag "deleted"
func (engine *Engine) Unscoped() *Session {
session := engine.NewSession()
session.isAutoClose = true
return session.Unscoped()
}
// CondDeleted returns the conditions whether a record is soft deleted.
func (engine *Engine) CondDeleted(colName string) builder.Cond {
if engine.dialect.DBType() == core.MSSQL {
return builder.IsNull{colName}
}
return builder.IsNull{colName}.Or(builder.Eq{colName: zeroTime1})
}
// BufferSize sets buffer size for iterate
func (engine *Engine) BufferSize(size int) *Session {
session := engine.NewSession()
session.isAutoClose = true
return session.BufferSize(size)
}

194
vendor/github.com/go-xorm/xorm/engine_group.go generated vendored Normal file
View File

@@ -0,0 +1,194 @@
// Copyright 2017 The Xorm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package xorm
import (
"github.com/go-xorm/core"
)
// EngineGroup defines an engine group
type EngineGroup struct {
*Engine
slaves []*Engine
policy GroupPolicy
}
// NewEngineGroup creates a new engine group
func NewEngineGroup(args1 interface{}, args2 interface{}, policies ...GroupPolicy) (*EngineGroup, error) {
var eg EngineGroup
if len(policies) > 0 {
eg.policy = policies[0]
} else {
eg.policy = RoundRobinPolicy()
}
driverName, ok1 := args1.(string)
conns, ok2 := args2.([]string)
if ok1 && ok2 {
engines := make([]*Engine, len(conns))
for i, conn := range conns {
engine, err := NewEngine(driverName, conn)
if err != nil {
return nil, err
}
engine.engineGroup = &eg
engines[i] = engine
}
eg.Engine = engines[0]
eg.slaves = engines[1:]
return &eg, nil
}
master, ok3 := args1.(*Engine)
slaves, ok4 := args2.([]*Engine)
if ok3 && ok4 {
master.engineGroup = &eg
for i := 0; i < len(slaves); i++ {
slaves[i].engineGroup = &eg
}
eg.Engine = master
eg.slaves = slaves
return &eg, nil
}
return nil, ErrParamsType
}
// Close the engine
func (eg *EngineGroup) Close() error {
err := eg.Engine.Close()
if err != nil {
return err
}
for i := 0; i < len(eg.slaves); i++ {
err := eg.slaves[i].Close()
if err != nil {
return err
}
}
return nil
}
// Master returns the master engine
func (eg *EngineGroup) Master() *Engine {
return eg.Engine
}
// Ping tests if database is alive
func (eg *EngineGroup) Ping() error {
if err := eg.Engine.Ping(); err != nil {
return err
}
for _, slave := range eg.slaves {
if err := slave.Ping(); err != nil {
return err
}
}
return nil
}
// SetColumnMapper set the column name mapping rule
func (eg *EngineGroup) SetColumnMapper(mapper core.IMapper) {
eg.Engine.ColumnMapper = mapper
for i := 0; i < len(eg.slaves); i++ {
eg.slaves[i].ColumnMapper = mapper
}
}
// SetDefaultCacher set the default cacher
func (eg *EngineGroup) SetDefaultCacher(cacher core.Cacher) {
eg.Engine.SetDefaultCacher(cacher)
for i := 0; i < len(eg.slaves); i++ {
eg.slaves[i].SetDefaultCacher(cacher)
}
}
// SetLogger set the new logger
func (eg *EngineGroup) SetLogger(logger core.ILogger) {
eg.Engine.SetLogger(logger)
for i := 0; i < len(eg.slaves); i++ {
eg.slaves[i].SetLogger(logger)
}
}
// SetLogLevel sets the logger level
func (eg *EngineGroup) SetLogLevel(level core.LogLevel) {
eg.Engine.SetLogLevel(level)
for i := 0; i < len(eg.slaves); i++ {
eg.slaves[i].SetLogLevel(level)
}
}
// SetMapper set the name mapping rules
func (eg *EngineGroup) SetMapper(mapper core.IMapper) {
eg.Engine.SetMapper(mapper)
for i := 0; i < len(eg.slaves); i++ {
eg.slaves[i].SetMapper(mapper)
}
}
// SetMaxIdleConns set the max idle connections on pool, default is 2
func (eg *EngineGroup) SetMaxIdleConns(conns int) {
eg.Engine.db.SetMaxIdleConns(conns)
for i := 0; i < len(eg.slaves); i++ {
eg.slaves[i].db.SetMaxIdleConns(conns)
}
}
// SetMaxOpenConns is only available for go 1.2+
func (eg *EngineGroup) SetMaxOpenConns(conns int) {
eg.Engine.db.SetMaxOpenConns(conns)
for i := 0; i < len(eg.slaves); i++ {
eg.slaves[i].db.SetMaxOpenConns(conns)
}
}
// SetPolicy set the group policy
func (eg *EngineGroup) SetPolicy(policy GroupPolicy) *EngineGroup {
eg.policy = policy
return eg
}
// SetTableMapper set the table name mapping rule
func (eg *EngineGroup) SetTableMapper(mapper core.IMapper) {
eg.Engine.TableMapper = mapper
for i := 0; i < len(eg.slaves); i++ {
eg.slaves[i].TableMapper = mapper
}
}
// ShowExecTime show SQL statement and execute time or not on logger if log level is great than INFO
func (eg *EngineGroup) ShowExecTime(show ...bool) {
eg.Engine.ShowExecTime(show...)
for i := 0; i < len(eg.slaves); i++ {
eg.slaves[i].ShowExecTime(show...)
}
}
// ShowSQL show SQL statement or not on logger if log level is great than INFO
func (eg *EngineGroup) ShowSQL(show ...bool) {
eg.Engine.ShowSQL(show...)
for i := 0; i < len(eg.slaves); i++ {
eg.slaves[i].ShowSQL(show...)
}
}
// Slave returns one of the physical databases which is a slave according the policy
func (eg *EngineGroup) Slave() *Engine {
switch len(eg.slaves) {
case 0:
return eg.Engine
case 1:
return eg.slaves[0]
}
return eg.policy.Slave(eg)
}
// Slaves returns all the slaves
func (eg *EngineGroup) Slaves() []*Engine {
return eg.slaves
}

116
vendor/github.com/go-xorm/xorm/engine_group_policy.go generated vendored Normal file
View File

@@ -0,0 +1,116 @@
// Copyright 2017 The Xorm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package xorm
import (
"math/rand"
"sync"
"time"
)
// GroupPolicy is be used by chosing the current slave from slaves
type GroupPolicy interface {
Slave(*EngineGroup) *Engine
}
// GroupPolicyHandler should be used when a function is a GroupPolicy
type GroupPolicyHandler func(*EngineGroup) *Engine
// Slave implements the chosen of slaves
func (h GroupPolicyHandler) Slave(eg *EngineGroup) *Engine {
return h(eg)
}
// RandomPolicy implmentes randomly chose the slave of slaves
func RandomPolicy() GroupPolicyHandler {
var r = rand.New(rand.NewSource(time.Now().UnixNano()))
return func(g *EngineGroup) *Engine {
return g.Slaves()[r.Intn(len(g.Slaves()))]
}
}
// WeightRandomPolicy implmentes randomly chose the slave of slaves
func WeightRandomPolicy(weights []int) GroupPolicyHandler {
var rands = make([]int, 0, len(weights))
for i := 0; i < len(weights); i++ {
for n := 0; n < weights[i]; n++ {
rands = append(rands, i)
}
}
var r = rand.New(rand.NewSource(time.Now().UnixNano()))
return func(g *EngineGroup) *Engine {
var slaves = g.Slaves()
idx := rands[r.Intn(len(rands))]
if idx >= len(slaves) {
idx = len(slaves) - 1
}
return slaves[idx]
}
}
func RoundRobinPolicy() GroupPolicyHandler {
var pos = -1
var lock sync.Mutex
return func(g *EngineGroup) *Engine {
var slaves = g.Slaves()
lock.Lock()
defer lock.Unlock()
pos++
if pos >= len(slaves) {
pos = 0
}
return slaves[pos]
}
}
func WeightRoundRobinPolicy(weights []int) GroupPolicyHandler {
var rands = make([]int, 0, len(weights))
for i := 0; i < len(weights); i++ {
for n := 0; n < weights[i]; n++ {
rands = append(rands, i)
}
}
var pos = -1
var lock sync.Mutex
return func(g *EngineGroup) *Engine {
var slaves = g.Slaves()
lock.Lock()
defer lock.Unlock()
pos++
if pos >= len(rands) {
pos = 0
}
idx := rands[pos]
if idx >= len(slaves) {
idx = len(slaves) - 1
}
return slaves[idx]
}
}
// LeastConnPolicy implements GroupPolicy, every time will get the least connections slave
func LeastConnPolicy() GroupPolicyHandler {
return func(g *EngineGroup) *Engine {
var slaves = g.Slaves()
connections := 0
idx := 0
for i := 0; i < len(slaves); i++ {
openConnections := slaves[i].DB().Stats().OpenConnections
if i == 0 {
connections = openConnections
idx = i
} else if openConnections <= connections {
connections = openConnections
idx = i
}
}
return slaves[idx]
}
}

View File

@@ -12,3 +12,11 @@ import "time"
func (engine *Engine) SetConnMaxLifetime(d time.Duration) {
engine.db.SetConnMaxLifetime(d)
}
// SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
func (eg *EngineGroup) SetConnMaxLifetime(d time.Duration) {
eg.Engine.SetConnMaxLifetime(d)
for i := 0; i < len(eg.slaves); i++ {
eg.slaves[i].SetConnMaxLifetime(d)
}
}

View File

@@ -23,4 +23,6 @@ var (
ErrNeedDeletedCond = errors.New("Delete need at least one condition")
// ErrNotImplemented not implemented
ErrNotImplemented = errors.New("Not implemented")
// ErrConditionType condition type unsupported
ErrConditionType = errors.New("Unsupported conditon type")
)

103
vendor/github.com/go-xorm/xorm/interface.go generated vendored Normal file
View File

@@ -0,0 +1,103 @@
// Copyright 2017 The Xorm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package xorm
import (
"database/sql"
"reflect"
"time"
"github.com/go-xorm/core"
)
// Interface defines the interface which Engine, EngineGroup and Session will implementate.
type Interface interface {
AllCols() *Session
Alias(alias string) *Session
Asc(colNames ...string) *Session
BufferSize(size int) *Session
Cols(columns ...string) *Session
Count(...interface{}) (int64, error)
CreateIndexes(bean interface{}) error
CreateUniques(bean interface{}) error
Decr(column string, arg ...interface{}) *Session
Desc(...string) *Session
Delete(interface{}) (int64, error)
Distinct(columns ...string) *Session
DropIndexes(bean interface{}) error
Exec(string, ...interface{}) (sql.Result, error)
Exist(bean ...interface{}) (bool, error)
Find(interface{}, ...interface{}) error
Get(interface{}) (bool, error)
GroupBy(keys string) *Session
ID(interface{}) *Session
In(string, ...interface{}) *Session
Incr(column string, arg ...interface{}) *Session
Insert(...interface{}) (int64, error)
InsertOne(interface{}) (int64, error)
IsTableEmpty(bean interface{}) (bool, error)
IsTableExist(beanOrTableName interface{}) (bool, error)
Iterate(interface{}, IterFunc) error
Limit(int, ...int) *Session
NoAutoCondition(...bool) *Session
NotIn(string, ...interface{}) *Session
Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *Session
Omit(columns ...string) *Session
OrderBy(order string) *Session
Ping() error
Query(sqlOrAgrs ...interface{}) (resultsSlice []map[string][]byte, err error)
QueryInterface(sqlorArgs ...interface{}) ([]map[string]interface{}, error)
QueryString(sqlorArgs ...interface{}) ([]map[string]string, error)
Rows(bean interface{}) (*Rows, error)
SetExpr(string, string) *Session
SQL(interface{}, ...interface{}) *Session
Sum(bean interface{}, colName string) (float64, error)
SumInt(bean interface{}, colName string) (int64, error)
Sums(bean interface{}, colNames ...string) ([]float64, error)
SumsInt(bean interface{}, colNames ...string) ([]int64, error)
Table(tableNameOrBean interface{}) *Session
Unscoped() *Session
Update(bean interface{}, condiBeans ...interface{}) (int64, error)
UseBool(...string) *Session
Where(interface{}, ...interface{}) *Session
}
// EngineInterface defines the interface which Engine, EngineGroup will implementate.
type EngineInterface interface {
Interface
Before(func(interface{})) *Session
Charset(charset string) *Session
CreateTables(...interface{}) error
DBMetas() ([]*core.Table, error)
Dialect() core.Dialect
DropTables(...interface{}) error
DumpAllToFile(fp string, tp ...core.DbType) error
GetColumnMapper() core.IMapper
GetDefaultCacher() core.Cacher
GetTableMapper() core.IMapper
GetTZDatabase() *time.Location
GetTZLocation() *time.Location
NewSession() *Session
NoAutoTime() *Session
Quote(string) string
SetDefaultCacher(core.Cacher)
SetLogLevel(core.LogLevel)
SetMapper(core.IMapper)
SetTZDatabase(tz *time.Location)
SetTZLocation(tz *time.Location)
ShowSQL(show ...bool)
Sync(...interface{}) error
Sync2(...interface{}) error
StoreEngine(storeEngine string) *Session
TableInfo(bean interface{}) *Table
UnMapType(reflect.Type)
}
var (
_ Interface = &Session{}
_ EngineInterface = &Engine{}
_ EngineInterface = &EngineGroup{}
)

View File

@@ -76,6 +76,7 @@ func (session *Session) Init() {
session.afterDeleteBeans = make(map[interface{}]*[]func(interface{}), 0)
session.beforeClosures = make([]func(interface{}), 0)
session.afterClosures = make([]func(interface{}), 0)
session.stmtCache = make(map[uint32]*core.Stmt)
session.afterProcessors = make([]executedProcessor, 0)
@@ -262,13 +263,13 @@ func (session *Session) canCache() bool {
return true
}
func (session *Session) doPrepare(sqlStr string) (stmt *core.Stmt, err error) {
func (session *Session) doPrepare(db *core.DB, sqlStr string) (stmt *core.Stmt, err error) {
crc := crc32.ChecksumIEEE([]byte(sqlStr))
// TODO try hash(sqlStr+len(sqlStr))
var has bool
stmt, has = session.stmtCache[crc]
if !has {
stmt, err = session.DB().Prepare(sqlStr)
stmt, err = db.Prepare(sqlStr)
if err != nil {
return nil, err
}
@@ -461,6 +462,10 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b
hasAssigned = true
if len(bs) > 0 {
if fieldType.Kind() == reflect.String {
fieldValue.SetString(string(bs))
continue
}
if fieldValue.CanAddr() {
err := json.Unmarshal(bs, fieldValue.Addr().Interface())
if err != nil {

View File

@@ -34,27 +34,27 @@ func (session *Session) str2Time(col *core.Column, data string) (outTime time.Ti
sd, err := strconv.ParseInt(sdata, 10, 64)
if err == nil {
x = time.Unix(sd, 0)
session.engine.logger.Debugf("time(0) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
//session.engine.logger.Debugf("time(0) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
} else {
session.engine.logger.Debugf("time(0) err key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
//session.engine.logger.Debugf("time(0) err key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
}
} else if len(sdata) > 19 && strings.Contains(sdata, "-") {
x, err = time.ParseInLocation(time.RFC3339Nano, sdata, parseLoc)
session.engine.logger.Debugf("time(1) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
if err != nil {
x, err = time.ParseInLocation("2006-01-02 15:04:05.999999999", sdata, parseLoc)
session.engine.logger.Debugf("time(2) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
//session.engine.logger.Debugf("time(2) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
}
if err != nil {
x, err = time.ParseInLocation("2006-01-02 15:04:05.9999999 Z07:00", sdata, parseLoc)
session.engine.logger.Debugf("time(3) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
//session.engine.logger.Debugf("time(3) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
}
} else if len(sdata) == 19 && strings.Contains(sdata, "-") {
x, err = time.ParseInLocation("2006-01-02 15:04:05", sdata, parseLoc)
session.engine.logger.Debugf("time(4) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
//session.engine.logger.Debugf("time(4) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
} else if len(sdata) == 10 && sdata[4] == '-' && sdata[7] == '-' {
x, err = time.ParseInLocation("2006-01-02", sdata, parseLoc)
session.engine.logger.Debugf("time(5) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
//session.engine.logger.Debugf("time(5) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
} else if col.SQLType.Name == core.Time {
if strings.Contains(sdata, " ") {
ssd := strings.Split(sdata, " ")
@@ -68,7 +68,7 @@ func (session *Session) str2Time(col *core.Column, data string) (outTime time.Ti
st := fmt.Sprintf("2006-01-02 %v", sdata)
x, err = time.ParseInLocation("2006-01-02 15:04:05", st, parseLoc)
session.engine.logger.Debugf("time(6) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
//session.engine.logger.Debugf("time(6) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
} else {
outErr = fmt.Errorf("unsupported time format %v", sdata)
return

View File

@@ -10,6 +10,7 @@ import (
"reflect"
"github.com/go-xorm/builder"
"github.com/go-xorm/core"
)
// Exist returns true if the record exist otherwise return false
@@ -35,10 +36,18 @@ func (session *Session) Exist(bean ...interface{}) (bool, error) {
return false, err
}
sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE %s LIMIT 1", tableName, condSQL)
if session.engine.dialect.DBType() == core.MSSQL {
sqlStr = fmt.Sprintf("SELECT top 1 * FROM %s WHERE %s", tableName, condSQL)
} else {
sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE %s LIMIT 1", tableName, condSQL)
}
args = condArgs
} else {
sqlStr = fmt.Sprintf("SELECT * FROM %s LIMIT 1", tableName)
if session.engine.dialect.DBType() == core.MSSQL {
sqlStr = fmt.Sprintf("SELECT top 1 * FROM %s", tableName)
} else {
sqlStr = fmt.Sprintf("SELECT * FROM %s LIMIT 1", tableName)
}
args = []interface{}{}
}
} else {

View File

@@ -5,6 +5,7 @@
package xorm
import (
"database/sql"
"errors"
"reflect"
"strconv"
@@ -79,6 +80,13 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bea
return false, nil
}
switch bean.(type) {
case sql.NullInt64, sql.NullBool, sql.NullFloat64, sql.NullString:
return true, rows.Scan(&bean)
case *sql.NullInt64, *sql.NullBool, *sql.NullFloat64, *sql.NullString:
return true, rows.Scan(bean)
}
switch beanKind {
case reflect.Struct:
fields, err := rows.Columns()

View File

@@ -400,7 +400,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
return 0, err
}
handleAfterInsertProcessorFunc(bean)
defer handleAfterInsertProcessorFunc(bean)
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
session.cacheInsert(table, tableName)
@@ -445,7 +445,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
if err != nil {
return 0, err
}
handleAfterInsertProcessorFunc(bean)
defer handleAfterInsertProcessorFunc(bean)
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
session.cacheInsert(table, tableName)

View File

@@ -8,17 +8,92 @@ import (
"fmt"
"reflect"
"strconv"
"strings"
"time"
"github.com/go-xorm/builder"
"github.com/go-xorm/core"
)
func (session *Session) genQuerySQL(sqlorArgs ...interface{}) (string, []interface{}, error) {
if len(sqlorArgs) > 0 {
switch sqlorArgs[0].(type) {
case string:
return sqlorArgs[0].(string), sqlorArgs[1:], nil
case *builder.Builder:
return sqlorArgs[0].(*builder.Builder).ToSQL()
case builder.Builder:
bd := sqlorArgs[0].(builder.Builder)
return bd.ToSQL()
default:
return "", nil, ErrUnSupportedType
}
}
if session.statement.RawSQL != "" {
return session.statement.RawSQL, session.statement.RawParams, nil
}
if len(session.statement.TableName()) <= 0 {
return "", nil, ErrTableNotFound
}
var columnStr = session.statement.ColumnStr
if len(session.statement.selectStr) > 0 {
columnStr = session.statement.selectStr
} else {
if session.statement.JoinStr == "" {
if columnStr == "" {
if session.statement.GroupByStr != "" {
columnStr = session.statement.Engine.Quote(strings.Replace(session.statement.GroupByStr, ",", session.engine.Quote(","), -1))
} else {
columnStr = session.statement.genColumnStr()
}
}
} else {
if columnStr == "" {
if session.statement.GroupByStr != "" {
columnStr = session.statement.Engine.Quote(strings.Replace(session.statement.GroupByStr, ",", session.engine.Quote(","), -1))
} else {
columnStr = "*"
}
}
}
if columnStr == "" {
columnStr = "*"
}
}
condSQL, condArgs, err := builder.ToSQL(session.statement.cond)
if err != nil {
return "", nil, err
}
args := append(session.statement.joinArgs, condArgs...)
sqlStr, err := session.statement.genSelectSQL(columnStr, condSQL)
if err != nil {
return "", nil, err
}
// for mssql and use limit
qs := strings.Count(sqlStr, "?")
if len(args)*2 == qs {
args = append(args, args...)
}
return sqlStr, args, nil
}
// Query runs a raw sql and return records as []map[string][]byte
func (session *Session) Query(sqlStr string, args ...interface{}) ([]map[string][]byte, error) {
func (session *Session) Query(sqlorArgs ...interface{}) ([]map[string][]byte, error) {
if session.isAutoClose {
defer session.Close()
}
sqlStr, args, err := session.genQuerySQL(sqlorArgs...)
if err != nil {
return nil, err
}
return session.queryBytes(sqlStr, args...)
}
@@ -114,11 +189,16 @@ func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error)
}
// QueryString runs a raw sql and return records as []map[string]string
func (session *Session) QueryString(sqlStr string, args ...interface{}) ([]map[string]string, error) {
func (session *Session) QueryString(sqlorArgs ...interface{}) ([]map[string]string, error) {
if session.isAutoClose {
defer session.Close()
}
sqlStr, args, err := session.genQuerySQL(sqlorArgs...)
if err != nil {
return nil, err
}
rows, err := session.queryRows(sqlStr, args...)
if err != nil {
return nil, err
@@ -162,11 +242,16 @@ func rows2Interfaces(rows *core.Rows) (resultsSlice []map[string]interface{}, er
}
// QueryInterface runs a raw sql and return records as []map[string]interface{}
func (session *Session) QueryInterface(sqlStr string, args ...interface{}) ([]map[string]interface{}, error) {
func (session *Session) QueryInterface(sqlorArgs ...interface{}) ([]map[string]interface{}, error) {
if session.isAutoClose {
defer session.Close()
}
sqlStr, args, err := session.genQuerySQL(sqlorArgs...)
if err != nil {
return nil, err
}
rows, err := session.queryRows(sqlStr, args...)
if err != nil {
return nil, err

View File

@@ -47,9 +47,16 @@ func (session *Session) queryRows(sqlStr string, args ...interface{}) (*core.Row
}
if session.isAutoCommit {
var db *core.DB
if session.engine.engineGroup != nil {
db = session.engine.engineGroup.Slave().DB()
} else {
db = session.DB()
}
if session.prepareStmt {
// don't clear stmt since session will cache them
stmt, err := session.doPrepare(sqlStr)
stmt, err := session.doPrepare(db, sqlStr)
if err != nil {
return nil, err
}
@@ -61,7 +68,7 @@ func (session *Session) queryRows(sqlStr string, args ...interface{}) (*core.Row
return rows, nil
}
rows, err := session.DB().Query(sqlStr, args...)
rows, err := db.Query(sqlStr, args...)
if err != nil {
return nil, err
}
@@ -171,7 +178,7 @@ func (session *Session) exec(sqlStr string, args ...interface{}) (sql.Result, er
}
if session.prepareStmt {
stmt, err := session.doPrepare(sqlStr)
stmt, err := session.doPrepare(session.DB(), sqlStr)
if err != nil {
return nil, err
}

View File

@@ -242,10 +242,23 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
var autoCond builder.Cond
if !session.statement.noAutoCondition && len(condiBean) > 0 {
var err error
autoCond, err = session.statement.buildConds(session.statement.RefTable, condiBean[0], true, true, false, true, false)
if err != nil {
return 0, err
if c, ok := condiBean[0].(map[string]interface{}); ok {
autoCond = builder.Eq(c)
} else {
ct := reflect.TypeOf(condiBean[0])
k := ct.Kind()
if k == reflect.Ptr {
k = ct.Elem().Kind()
}
if k == reflect.Struct {
var err error
autoCond, err = session.statement.buildConds(session.statement.RefTable, condiBean[0], true, true, false, true, false)
if err != nil {
return 0, err
}
} else {
return 0, ErrConditionType
}
}
}

View File

@@ -160,6 +160,9 @@ func (statement *Statement) And(query interface{}, args ...interface{}) *Stateme
case string:
cond := builder.Expr(query.(string), args...)
statement.cond = statement.cond.And(cond)
case map[string]interface{}:
cond := builder.Eq(query.(map[string]interface{}))
statement.cond = statement.cond.And(cond)
case builder.Cond:
cond := query.(builder.Cond)
statement.cond = statement.cond.And(cond)
@@ -181,6 +184,9 @@ func (statement *Statement) Or(query interface{}, args ...interface{}) *Statemen
case string:
cond := builder.Expr(query.(string), args...)
statement.cond = statement.cond.Or(cond)
case map[string]interface{}:
cond := builder.Eq(query.(map[string]interface{}))
statement.cond = statement.cond.Or(cond)
case builder.Cond:
cond := query.(builder.Cond)
statement.cond = statement.cond.Or(cond)
@@ -901,8 +907,12 @@ func (statement *Statement) genDelIndexSQL() []string {
func (statement *Statement) genAddColumnStr(col *core.Column) (string, []interface{}) {
quote := statement.Engine.Quote
sql := fmt.Sprintf("ALTER TABLE %v ADD %v;", quote(statement.TableName()),
sql := fmt.Sprintf("ALTER TABLE %v ADD %v", quote(statement.TableName()),
col.String(statement.Engine.dialect))
if statement.Engine.dialect.DBType() == core.MYSQL && len(col.Comment) > 0 {
sql += " COMMENT '" + col.Comment + "'"
}
sql += ";"
return sql, []interface{}{}
}

18
vendor/vendor.json vendored
View File

@@ -462,16 +462,16 @@
"revisionTime": "2016-11-01T11:13:14Z"
},
{
"checksumSHA1": "9SXbj96wb1PgppBZzxMIN0axbFQ=",
"checksumSHA1": "HsUSlgz1VKEEiZdkXY5qdLzexWU=",
"path": "github.com/go-xorm/builder",
"revision": "c8871c857d2555fbfbd8524f895be5386d3d8836",
"revisionTime": "2017-05-19T03:21:30Z"
"revision": "488224409dd8aa2ce7a5baf8d10d55764a913738",
"revisionTime": "2018-01-16T06:54:19Z"
},
{
"checksumSHA1": "HMavuxvDhKOwmbbFnYt9hfT6jE0=",
"checksumSHA1": "7JjlvSpGfLa49MHElks8NGBUfFA=",
"path": "github.com/go-xorm/core",
"revision": "da1adaf7a28ca792961721a34e6e04945200c890",
"revisionTime": "2017-09-09T08:56:53Z"
"revision": "cb1d0ca71f42d3ee1bf4aba7daa16099bc31a7e9",
"revisionTime": "2017-12-21T01:38:49Z"
},
{
"checksumSHA1": "k52lEKLp8j5M+jFpe+3u+bIFpxQ=",
@@ -480,10 +480,10 @@
"revisionTime": "2016-08-11T02:11:45Z"
},
{
"checksumSHA1": "+KmPfckyKvrUZPIHBYHylg/7V8o=",
"checksumSHA1": "eGBz6F3I/0naVUclZ6GZWc3EzQo=",
"path": "github.com/go-xorm/xorm",
"revision": "29d4a0330a00b9be468b70e3fb0f74109348c358",
"revisionTime": "2017-09-30T01:26:13Z"
"revision": "d4149d1eee0c2c488a74a5863fd9caf13d60fd03",
"revisionTime": "2018-01-22T13:32:35Z"
},
{
"checksumSHA1": "1ft/4j5MFa7C9dPI9whL03HSUzk=",