# Conflicts:
#	models/migrations/migrations.go
#	models/migrations/v59.go
#	modules/auth/repo_form.go
This commit is contained in:
kolaente 2018-04-03 11:16:37 +02:00
commit a25e1dd0cf
No known key found for this signature in database
GPG Key ID: F40E70337AB24C9B
64 changed files with 489 additions and 248 deletions

View File

@ -210,6 +210,8 @@ PATH = data/gitea.db
SQLITE_TIMEOUT = 500 SQLITE_TIMEOUT = 500
; For iterate buffer, default is 50 ; For iterate buffer, default is 50
ITERATE_BUFFER_SIZE = 50 ITERATE_BUFFER_SIZE = 50
; Show the database generated SQL
LOG_SQL = true
[indexer] [indexer]
ISSUE_INDEXER_PATH = indexers/issues.bleve ISSUE_INDEXER_PATH = indexers/issues.bleve

View File

@ -1,5 +1,7 @@
#!/bin/bash #!/bin/bash
/usr/sbin/update-ca-certificates
if [ ! -d /data/git/.ssh ]; then if [ ! -d /data/git/.ssh ]; then
mkdir -p /data/git/.ssh mkdir -p /data/git/.ssh
chmod 700 /data/git/.ssh chmod 700 /data/git/.ssh

View File

@ -121,6 +121,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `PASSWD`: **\<empty\>**: Database user password. Use \`your password\` for quoting if you use special characters in the 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. - `SSL_MODE`: **disable**: For PostgreSQL only.
- `PATH`: **data/gitea.db**: For SQLite3 only, the database file path. - `PATH`: **data/gitea.db**: For SQLite3 only, the database file path.
- `LOG_SQL`: **true**: Log the executed SQL.
## Indexer (`indexer`) ## Indexer (`indexer`)

View File

@ -80,6 +80,7 @@ menu:
- `PASSWD`: 数据库用户密码。 - `PASSWD`: 数据库用户密码。
- `SSL_MODE`: PostgreSQL数据库是否启用SSL模式。 - `SSL_MODE`: PostgreSQL数据库是否启用SSL模式。
- `PATH`: Tidb 或者 SQLite3 数据文件存放路径。 - `PATH`: Tidb 或者 SQLite3 数据文件存放路径。
- `LOG_SQL`: **true**: 显示生成的SQL默认为真。
## Security (`security`) ## Security (`security`)

View File

@ -527,6 +527,11 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
return fmt.Errorf("GetRepositoryByName [owner_id: %d, name: %s]: %v", opts.RepoOwnerID, opts.RepoName, err) return fmt.Errorf("GetRepositoryByName [owner_id: %d, name: %s]: %v", opts.RepoOwnerID, opts.RepoName, err)
} }
refName := git.RefEndName(opts.RefFullName)
if repo.IsBare && refName != repo.DefaultBranch {
repo.DefaultBranch = refName
}
// Change repository bare status and update last updated time. // Change repository bare status and update last updated time.
repo.IsBare = repo.IsBare && opts.Commits.Len <= 0 repo.IsBare = repo.IsBare && opts.Commits.Len <= 0
if err = UpdateRepository(repo, false); err != nil { if err = UpdateRepository(repo, false); err != nil {
@ -567,7 +572,6 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
return fmt.Errorf("Marshal: %v", err) return fmt.Errorf("Marshal: %v", err)
} }
refName := git.RefEndName(opts.RefFullName)
if err = NotifyWatchers(&Action{ if err = NotifyWatchers(&Action{
ActUserID: pusher.ID, ActUserID: pusher.ID,
ActUser: pusher, ActUser: pusher,

View File

@ -11,7 +11,6 @@ import (
"os" "os"
"path" "path"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
api "code.gitea.io/sdk/gitea" api "code.gitea.io/sdk/gitea"
@ -29,6 +28,7 @@ type Attachment struct {
CommentID int64 CommentID int64
Name string Name string
DownloadCount int64 `xorm:"DEFAULT 0"` DownloadCount int64 `xorm:"DEFAULT 0"`
Size int64 `xorm:"DEFAULT 0"`
CreatedUnix util.TimeStamp `xorm:"created"` CreatedUnix util.TimeStamp `xorm:"created"`
} }
@ -44,13 +44,12 @@ func (a *Attachment) IncreaseDownloadCount() error {
// APIFormat converts models.Attachment to api.Attachment // APIFormat converts models.Attachment to api.Attachment
func (a *Attachment) APIFormat() *api.Attachment { func (a *Attachment) APIFormat() *api.Attachment {
size, _ := a.Size()
return &api.Attachment{ return &api.Attachment{
ID: a.ID, ID: a.ID,
Name: a.Name, Name: a.Name,
Created: a.CreatedUnix.AsTime(), Created: a.CreatedUnix.AsTime(),
DownloadCount: a.DownloadCount, DownloadCount: a.DownloadCount,
Size: size, Size: a.Size,
UUID: a.UUID, UUID: a.UUID,
DownloadURL: a.DownloadURL(), DownloadURL: a.DownloadURL(),
} }
@ -67,25 +66,6 @@ func (a *Attachment) LocalPath() string {
return AttachmentLocalPath(a.UUID) return AttachmentLocalPath(a.UUID)
} }
// Size returns the file's size of the attachment
func (a *Attachment) Size() (int64, error) {
fi, err := os.Stat(a.LocalPath())
if err != nil {
return 0, err
}
return fi.Size(), nil
}
// MustSize returns the result of a.Size() by ignoring errors
func (a *Attachment) MustSize() int64 {
size, err := a.Size()
if err != nil {
log.Error(4, "size: %v", err)
return 0
}
return size
}
// DownloadURL returns the download url of the attached file // DownloadURL returns the download url of the attached file
func (a *Attachment) DownloadURL() string { func (a *Attachment) DownloadURL() string {
return fmt.Sprintf("%sattachments/%s", setting.AppURL, a.UUID) return fmt.Sprintf("%sattachments/%s", setting.AppURL, a.UUID)
@ -115,6 +95,13 @@ func NewAttachment(name string, buf []byte, file multipart.File) (_ *Attachment,
return nil, fmt.Errorf("Copy: %v", err) return nil, fmt.Errorf("Copy: %v", err)
} }
// Update file size
var fi os.FileInfo
if fi, err = fw.Stat(); err != nil {
return nil, fmt.Errorf("file size: %v", err)
}
attach.Size = fi.Size()
if _, err := x.Insert(attach); err != nil { if _, err := x.Insert(attach); err != nil {
return nil, err return nil, err
} }

View File

@ -23,15 +23,18 @@ const (
// ProtectedBranch struct // ProtectedBranch struct
type ProtectedBranch struct { type ProtectedBranch struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"UNIQUE(s)"` RepoID int64 `xorm:"UNIQUE(s)"`
BranchName string `xorm:"UNIQUE(s)"` BranchName string `xorm:"UNIQUE(s)"`
CanPush bool `xorm:"NOT NULL DEFAULT false"` CanPush bool `xorm:"NOT NULL DEFAULT false"`
EnableWhitelist bool EnableWhitelist bool
WhitelistUserIDs []int64 `xorm:"JSON TEXT"` WhitelistUserIDs []int64 `xorm:"JSON TEXT"`
WhitelistTeamIDs []int64 `xorm:"JSON TEXT"` WhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
CreatedUnix util.TimeStamp `xorm:"created"` EnableMergeWhitelist bool `xorm:"NOT NULL DEFAULT false"`
UpdatedUnix util.TimeStamp `xorm:"updated"` MergeWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
MergeWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
CreatedUnix util.TimeStamp `xorm:"created"`
UpdatedUnix util.TimeStamp `xorm:"updated"`
} }
// IsProtected returns if the branch is protected // IsProtected returns if the branch is protected
@ -61,6 +64,28 @@ func (protectBranch *ProtectedBranch) CanUserPush(userID int64) bool {
return in return in
} }
// CanUserMerge returns if some user could merge a pull request to this protected branch
func (protectBranch *ProtectedBranch) CanUserMerge(userID int64) bool {
if !protectBranch.EnableMergeWhitelist {
return true
}
if base.Int64sContains(protectBranch.MergeWhitelistUserIDs, userID) {
return true
}
if len(protectBranch.WhitelistTeamIDs) == 0 {
return false
}
in, err := IsUserInTeams(userID, protectBranch.MergeWhitelistTeamIDs)
if err != nil {
log.Error(1, "IsUserInTeams:", err)
return false
}
return in
}
// GetProtectedBranchByRepoID getting protected branch by repo ID // GetProtectedBranchByRepoID getting protected branch by repo ID
func GetProtectedBranchByRepoID(RepoID int64) ([]*ProtectedBranch, error) { func GetProtectedBranchByRepoID(RepoID int64) ([]*ProtectedBranch, error) {
protectedBranches := make([]*ProtectedBranch, 0) protectedBranches := make([]*ProtectedBranch, 0)
@ -97,40 +122,35 @@ func GetProtectedBranchByID(id int64) (*ProtectedBranch, error) {
// If ID is 0, it creates a new record. Otherwise, updates existing record. // If ID is 0, it creates a new record. Otherwise, updates existing record.
// This function also performs check if whitelist user and team's IDs have been changed // This function also performs check if whitelist user and team's IDs have been changed
// to avoid unnecessary whitelist delete and regenerate. // to avoid unnecessary whitelist delete and regenerate.
func UpdateProtectBranch(repo *Repository, protectBranch *ProtectedBranch, whitelistUserIDs, whitelistTeamIDs []int64) (err error) { func UpdateProtectBranch(repo *Repository, protectBranch *ProtectedBranch, whitelistUserIDs, whitelistTeamIDs, mergeWhitelistUserIDs, mergeWhitelistTeamIDs []int64) (err error) {
if err = repo.GetOwner(); err != nil { if err = repo.GetOwner(); err != nil {
return fmt.Errorf("GetOwner: %v", err) return fmt.Errorf("GetOwner: %v", err)
} }
hasUsersChanged := !util.IsSliceInt64Eq(protectBranch.WhitelistUserIDs, whitelistUserIDs) whitelist, err := updateUserWhitelist(repo, protectBranch.WhitelistUserIDs, whitelistUserIDs)
if hasUsersChanged { if err != nil {
protectBranch.WhitelistUserIDs = make([]int64, 0, len(whitelistUserIDs)) return err
for _, userID := range whitelistUserIDs {
has, err := hasAccess(x, userID, repo, AccessModeWrite)
if err != nil {
return fmt.Errorf("HasAccess [user_id: %d, repo_id: %d]: %v", userID, protectBranch.RepoID, err)
} else if !has {
continue // Drop invalid user ID
}
protectBranch.WhitelistUserIDs = append(protectBranch.WhitelistUserIDs, userID)
}
} }
protectBranch.WhitelistUserIDs = whitelist
// if the repo is in an orgniziation whitelist, err = updateUserWhitelist(repo, protectBranch.MergeWhitelistUserIDs, mergeWhitelistUserIDs)
hasTeamsChanged := !util.IsSliceInt64Eq(protectBranch.WhitelistTeamIDs, whitelistTeamIDs) if err != nil {
if hasTeamsChanged { return err
teams, err := GetTeamsWithAccessToRepo(repo.OwnerID, repo.ID, AccessModeWrite)
if err != nil {
return fmt.Errorf("GetTeamsWithAccessToRepo [org_id: %d, repo_id: %d]: %v", repo.OwnerID, repo.ID, err)
}
protectBranch.WhitelistTeamIDs = make([]int64, 0, len(teams))
for i := range teams {
if teams[i].HasWriteAccess() && com.IsSliceContainsInt64(whitelistTeamIDs, teams[i].ID) {
protectBranch.WhitelistTeamIDs = append(protectBranch.WhitelistTeamIDs, teams[i].ID)
}
}
} }
protectBranch.MergeWhitelistUserIDs = whitelist
// if the repo is in an organization
whitelist, err = updateTeamWhitelist(repo, protectBranch.WhitelistTeamIDs, whitelistTeamIDs)
if err != nil {
return err
}
protectBranch.WhitelistTeamIDs = whitelist
whitelist, err = updateTeamWhitelist(repo, protectBranch.MergeWhitelistTeamIDs, mergeWhitelistTeamIDs)
if err != nil {
return err
}
protectBranch.MergeWhitelistTeamIDs = whitelist
// Make sure protectBranch.ID is not 0 for whitelists // Make sure protectBranch.ID is not 0 for whitelists
if protectBranch.ID == 0 { if protectBranch.ID == 0 {
@ -174,6 +194,73 @@ func (repo *Repository) IsProtectedBranch(branchName string, doer *User) (bool,
return false, nil return false, nil
} }
// IsProtectedBranchForMerging checks if branch is protected for merging
func (repo *Repository) IsProtectedBranchForMerging(branchName string, doer *User) (bool, error) {
if doer == nil {
return true, nil
}
protectedBranch := &ProtectedBranch{
RepoID: repo.ID,
BranchName: branchName,
}
has, err := x.Get(protectedBranch)
if err != nil {
return true, err
} else if has {
return !protectedBranch.CanUserMerge(doer.ID), nil
}
return false, nil
}
// updateUserWhitelist checks whether the user whitelist changed and returns a whitelist with
// the users from newWhitelist which have write access to the repo.
func updateUserWhitelist(repo *Repository, currentWhitelist, newWhitelist []int64) (whitelist []int64, err error) {
hasUsersChanged := !util.IsSliceInt64Eq(currentWhitelist, newWhitelist)
if !hasUsersChanged {
return currentWhitelist, nil
}
whitelist = make([]int64, 0, len(newWhitelist))
for _, userID := range newWhitelist {
has, err := hasAccess(x, userID, repo, AccessModeWrite)
if err != nil {
return nil, fmt.Errorf("HasAccess [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err)
} else if !has {
continue // Drop invalid user ID
}
whitelist = append(whitelist, userID)
}
return
}
// updateTeamWhitelist checks whether the team whitelist changed and returns a whitelist with
// the teams from newWhitelist which have write access to the repo.
func updateTeamWhitelist(repo *Repository, currentWhitelist, newWhitelist []int64) (whitelist []int64, err error) {
hasTeamsChanged := !util.IsSliceInt64Eq(currentWhitelist, newWhitelist)
if !hasTeamsChanged {
return currentWhitelist, nil
}
teams, err := GetTeamsWithAccessToRepo(repo.OwnerID, repo.ID, AccessModeWrite)
if err != nil {
return nil, fmt.Errorf("GetTeamsWithAccessToRepo [org_id: %d, repo_id: %d]: %v", repo.OwnerID, repo.ID, err)
}
whitelist = make([]int64, 0, len(teams))
for i := range teams {
if teams[i].HasWriteAccess() && com.IsSliceContainsInt64(newWhitelist, teams[i].ID) {
whitelist = append(whitelist, teams[i].ID)
}
}
return
}
// DeleteProtectedBranch removes ProtectedBranch relation between the user and repository. // DeleteProtectedBranch removes ProtectedBranch relation between the user and repository.
func (repo *Repository) DeleteProtectedBranch(id int64) (err error) { func (repo *Repository) DeleteProtectedBranch(id int64) (err error) {
protectedBranch := &ProtectedBranch{ protectedBranch := &ProtectedBranch{

View File

@ -21,16 +21,16 @@ func assertLineEqual(t *testing.T, d1 *DiffLine, d2 *DiffLine) {
func TestDiffToHTML(t *testing.T) { func TestDiffToHTML(t *testing.T) {
assertEqual(t, "+foo <span class=\"added-code\">bar</span> biz", diffToHTML([]dmp.Diff{ assertEqual(t, "+foo <span class=\"added-code\">bar</span> biz", diffToHTML([]dmp.Diff{
{dmp.DiffEqual, "foo "}, {Type: dmp.DiffEqual, Text: "foo "},
{dmp.DiffInsert, "bar"}, {Type: dmp.DiffInsert, Text: "bar"},
{dmp.DiffDelete, " baz"}, {Type: dmp.DiffDelete, Text: " baz"},
{dmp.DiffEqual, " biz"}, {Type: dmp.DiffEqual, Text: " biz"},
}, DiffLineAdd)) }, DiffLineAdd))
assertEqual(t, "-foo <span class=\"removed-code\">bar</span> biz", diffToHTML([]dmp.Diff{ assertEqual(t, "-foo <span class=\"removed-code\">bar</span> biz", diffToHTML([]dmp.Diff{
{dmp.DiffEqual, "foo "}, {Type: dmp.DiffEqual, Text: "foo "},
{dmp.DiffDelete, "bar"}, {Type: dmp.DiffDelete, Text: "bar"},
{dmp.DiffInsert, " baz"}, {Type: dmp.DiffInsert, Text: " baz"},
{dmp.DiffEqual, " biz"}, {Type: dmp.DiffEqual, Text: " biz"},
}, DiffLineDel)) }, DiffLineDel))
} }

View File

@ -171,6 +171,12 @@ var migrations = []Migration{
// v58 -> v59 // v58 -> v59
NewMigration("add label descriptions", addLabelsDescriptions), NewMigration("add label descriptions", addLabelsDescriptions),
// v59 -> v60 // v59 -> v60
NewMigration("add merge whitelist for protected branches", addProtectedBranchMergeWhitelist),
// v60 -> v61
NewMigration("add is_fsck_enabled column for repos", addFsckEnabledToRepo),
// v61 -> v62
NewMigration("add size column for attachments", addSizeToAttachment),
// v62 -> v63
NewMigration("add issue_dependencies", addIssueDependencies), NewMigration("add issue_dependencies", addIssueDependencies),
} }

View File

@ -6,95 +6,19 @@ package migrations
import ( import (
"fmt" "fmt"
"time"
"code.gitea.io/gitea/modules/setting"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
) )
func addIssueDependencies(x *xorm.Engine) (err error) { func addProtectedBranchMergeWhitelist(x *xorm.Engine) error {
type ProtectedBranch struct {
type IssueDependency struct { EnableMergeWhitelist bool `xorm:"NOT NULL DEFAULT false"`
ID int64 `xorm:"pk autoincr"` MergeWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
UserID int64 `xorm:"NOT NULL"` MergeWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
IssueID int64 `xorm:"NOT NULL"`
DependencyID int64 `xorm:"NOT NULL"`
Created time.Time `xorm:"-"`
CreatedUnix int64 `xorm:"INDEX created"`
Updated time.Time `xorm:"-"`
UpdatedUnix int64 `xorm:"updated"`
} }
if err = x.Sync(new(IssueDependency)); err != nil { if err := x.Sync2(new(ProtectedBranch)); err != nil {
return fmt.Errorf("Error creating issue_dependency_table column definition: %v", err) return fmt.Errorf("Sync2: %v", err)
} }
return nil
// Update Comment definition
// This (copied) struct does only contain fields used by xorm as the only use here is to update the database
// CommentType defines the comment type
type CommentType int
// TimeStamp defines a timestamp
type TimeStamp int64
type Comment struct {
ID int64 `xorm:"pk autoincr"`
Type CommentType
PosterID int64 `xorm:"INDEX"`
IssueID int64 `xorm:"INDEX"`
LabelID int64
OldMilestoneID int64
MilestoneID int64
OldAssigneeID int64
AssigneeID int64
OldTitle string
NewTitle string
DependentIssueID int64
CommitID int64
Line int64
Content string `xorm:"TEXT"`
CreatedUnix TimeStamp `xorm:"INDEX created"`
UpdatedUnix TimeStamp `xorm:"INDEX updated"`
// Reference issue in commit message
CommitSHA string `xorm:"VARCHAR(40)"`
}
if err = x.Sync(new(Comment)); err != nil {
return fmt.Errorf("Error updating issue_comment table column definition: %v", err)
}
// RepoUnit describes all units of a repository
type RepoUnit struct {
ID int64
RepoID int64 `xorm:"INDEX(s)"`
Type int `xorm:"INDEX(s)"`
Config map[string]interface{} `xorm:"JSON"`
CreatedUnix int64 `xorm:"INDEX CREATED"`
Created time.Time `xorm:"-"`
}
//Updating existing issue units
units := make([]*RepoUnit, 0, 100)
err = x.Where("`type` = ?", V16UnitTypeIssues).Find(&units)
if err != nil {
return fmt.Errorf("Query repo units: %v", err)
}
for _, unit := range units {
if unit.Config == nil {
unit.Config = make(map[string]interface{})
}
if _, ok := unit.Config["EnableDependencies"]; !ok {
unit.Config["EnableDependencies"] = setting.Service.DefaultEnableDependencies
}
if _, err := x.ID(unit.ID).Cols("config").Update(unit); err != nil {
return err
}
}
return err
} }

22
models/migrations/v60.go Normal file
View File

@ -0,0 +1,22 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package migrations
import (
"fmt"
"github.com/go-xorm/xorm"
)
func addFsckEnabledToRepo(x *xorm.Engine) error {
type Repository struct {
IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"`
}
if err := x.Sync2(new(Repository)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
return nil
}

45
models/migrations/v61.go Normal file
View File

@ -0,0 +1,45 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package migrations
import (
"fmt"
"os"
"path"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/go-xorm/xorm"
)
func addSizeToAttachment(x *xorm.Engine) error {
type Attachment struct {
ID int64 `xorm:"pk autoincr"`
UUID string `xorm:"uuid UNIQUE"`
Size int64 `xorm:"DEFAULT 0"`
}
if err := x.Sync2(new(Attachment)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
attachments := make([]Attachment, 0, 100)
if err := x.Find(&attachments); err != nil {
return fmt.Errorf("query attachments: %v", err)
}
for _, attach := range attachments {
localPath := path.Join(setting.AttachmentPath, attach.UUID[0:1], attach.UUID[1:2], attach.UUID)
fi, err := os.Stat(localPath)
if err != nil {
log.Error(4, "calculate file size of attachment[UUID: %s]: %v", attach.UUID, err)
continue
}
attach.Size = fi.Size()
if _, err := x.ID(attach.ID).Cols("size").Update(attach); err != nil {
return fmt.Errorf("update size column: %v", err)
}
}
return nil
}

1
models/migrations/v62.go Normal file
View File

@ -0,0 +1 @@
package migrations

View File

@ -271,7 +271,7 @@ func SetEngine() (err error) {
// WARNING: for serv command, MUST remove the output to os.stdout, // WARNING: for serv command, MUST remove the output to os.stdout,
// so use log file to instead print to stdout. // so use log file to instead print to stdout.
x.SetLogger(log.XORMLogger) x.SetLogger(log.XORMLogger)
x.ShowSQL(true) x.ShowSQL(setting.LogSQL)
return nil return nil
} }

View File

@ -286,7 +286,7 @@ func (pr *PullRequest) CheckUserAllowedToMerge(doer *User) (err error) {
} }
} }
if protected, err := pr.BaseRepo.IsProtectedBranch(pr.BaseBranch, doer); err != nil { if protected, err := pr.BaseRepo.IsProtectedBranchForMerging(pr.BaseBranch, doer); err != nil {
return fmt.Errorf("IsProtectedBranch: %v", err) return fmt.Errorf("IsProtectedBranch: %v", err)
} else if protected { } else if protected {
return ErrNotAllowedToMerge{ return ErrNotAllowedToMerge{

View File

@ -198,6 +198,7 @@ type Repository struct {
BaseRepo *Repository `xorm:"-"` BaseRepo *Repository `xorm:"-"`
Size int64 `xorm:"NOT NULL DEFAULT 0"` Size int64 `xorm:"NOT NULL DEFAULT 0"`
IndexerStatus *RepoIndexerStatus `xorm:"-"` IndexerStatus *RepoIndexerStatus `xorm:"-"`
IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"` CreatedUnix util.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
@ -2177,12 +2178,12 @@ func GitFsck() {
log.Trace("Doing: GitFsck") log.Trace("Doing: GitFsck")
if err := x. if err := x.
Where("id>0").BufferSize(setting.IterateBufferSize). Where("id>0 AND is_fsck_enabled=?", true).BufferSize(setting.IterateBufferSize).
Iterate(new(Repository), Iterate(new(Repository),
func(idx int, bean interface{}) error { func(idx int, bean interface{}) error {
repo := bean.(*Repository) repo := bean.(*Repository)
repoPath := repo.RepoPath() repoPath := repo.RepoPath()
log.Trace(fmt.Sprintf("Running health check for repository %s", repoPath)) log.Trace("Running health check on repository %s", repoPath)
if err := git.Fsck(repoPath, setting.Cron.RepoHealthCheck.Timeout, setting.Cron.RepoHealthCheck.Args...); err != nil { if err := git.Fsck(repoPath, setting.Cron.RepoHealthCheck.Timeout, setting.Cron.RepoHealthCheck.Args...); err != nil {
desc := fmt.Sprintf("Failed to health check repository (%s): %v", repoPath, err) desc := fmt.Sprintf("Failed to health check repository (%s): %v", repoPath, err)
log.Warn(desc) log.Warn(desc)

View File

@ -114,6 +114,9 @@ type RepoSettingForm struct {
EnableTimetracker bool EnableTimetracker bool
AllowOnlyContributorsToTrackTime bool AllowOnlyContributorsToTrackTime bool
EnableIssueDependencies bool EnableIssueDependencies bool
// Admin settings
EnableHealthCheck bool
} }
// Validate validates the fields // Validate validates the fields
@ -130,10 +133,13 @@ func (f *RepoSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) bi
// ProtectBranchForm form for changing protected branch settings // ProtectBranchForm form for changing protected branch settings
type ProtectBranchForm struct { type ProtectBranchForm struct {
Protected bool Protected bool
EnableWhitelist bool EnableWhitelist bool
WhitelistUsers string WhitelistUsers string
WhitelistTeams string WhitelistTeams string
EnableMergeWhitelist bool
MergeWhitelistUsers string
MergeWhitelistTeams string
} }
// Validate validates the fields // Validate validates the fields

View File

@ -159,6 +159,7 @@ var (
UseMSSQL bool UseMSSQL bool
UsePostgreSQL bool UsePostgreSQL bool
UseTiDB bool UseTiDB bool
LogSQL bool
// Indexer settings // Indexer settings
Indexer struct { Indexer struct {
@ -931,6 +932,7 @@ func NewContext() {
} }
} }
IterateBufferSize = Cfg.Section("database").Key("ITERATE_BUFFER_SIZE").MustInt(50) IterateBufferSize = Cfg.Section("database").Key("ITERATE_BUFFER_SIZE").MustInt(50)
LogSQL = Cfg.Section("database").Key("LOG_SQL").MustBool(true)
sec = Cfg.Section("attachment") sec = Cfg.Section("attachment")
AttachmentPath = sec.Key("PATH").MustString(path.Join(AppDataPath, "attachments")) AttachmentPath = sec.Key("PATH").MustString(path.Join(AppDataPath, "attachments"))

View File

@ -639,13 +639,13 @@ issues.label_templates.use=Dieses Label Set benutzen
issues.label_templates.fail_to_load_file=Fehler beim Laden der Label Template Datei '%s': %v issues.label_templates.fail_to_load_file=Fehler beim Laden der Label Template Datei '%s': %v
issues.add_label_at=hat das <div class="ui label"style="color: %s\; background-color: %s">%s</div>-Label %s hinzugefügt issues.add_label_at=hat das <div class="ui label"style="color: %s\; background-color: %s">%s</div>-Label %s hinzugefügt
issues.remove_label_at=hat das <div class="ui label"style="color: %s\; background-color: %s">%s</div>-Label %s entfernt issues.remove_label_at=hat das <div class="ui label"style="color: %s\; background-color: %s">%s</div>-Label %s entfernt
issues.add_milestone_at=`fügte das Issue zum <b>%s</b> Meilenstein hinzu %s` issues.add_milestone_at=`hat diesen Issue %[2]s zum <b>%[1]s</b> Meilenstein hinzugefügt`
issues.change_milestone_at=`änderte den Meilenstein von <b>%s</b> zu <b>%s</b> %s` issues.change_milestone_at=`hat den Meilenstein %[3]s von <b>%[1]s</b> zu <b>%[2]s</b> geändert`
issues.remove_milestone_at=`entfernte das Issue vom <b>%s</b> Meilenstein %s` issues.remove_milestone_at=`hat diesen Issue %[2]s vom <b>%[1]s</b> Meilenstein entfernt`
issues.deleted_milestone=`(gelöscht)` issues.deleted_milestone=`(gelöscht)`
issues.self_assign_at=`wies sich das Issue selbst zu %s` issues.self_assign_at=`hat sich das Issue %s selbst zugewiesen`
issues.add_assignee_at=`wurde zugewiesen von <b>%s</b> %s` issues.add_assignee_at=`wurde %[1]s zugewiesen von <b>%[2]s</b>`
issues.remove_assignee_at=`entfernte seine Zuweisung %s` issues.remove_assignee_at=`hat seine Zuweisung %s entfernt`
issues.change_title_at=`Titel von <b>%s</b> nach <b>%s</b> %s geändert` issues.change_title_at=`Titel von <b>%s</b> nach <b>%s</b> %s geändert`
issues.delete_branch_at=`löschte die Branch <b>%s</b> %s` issues.delete_branch_at=`löschte die Branch <b>%s</b> %s`
issues.open_tab=%d offen issues.open_tab=%d offen
@ -675,14 +675,14 @@ issues.action_milestone=Meilenstein
issues.action_milestone_no_select=Kein Meilenstein issues.action_milestone_no_select=Kein Meilenstein
issues.action_assignee=Zuständig issues.action_assignee=Zuständig
issues.action_assignee_no_select=Niemand zuständig issues.action_assignee_no_select=Niemand zuständig
issues.opened_by=%[1]s geöffnet von <a href="%[2]s">%[3]s</a> issues.opened_by=%[1]s von <a href="%[2]s">%[3]s</a> geöffnet
issues.opened_by_fake=geöffnet %[1]s von %[2]s issues.opened_by_fake=geöffnet %[1]s von %[2]s
issues.previous=Vorherige issues.previous=Vorherige
issues.next=Nächste issues.next=Nächste
issues.open_title=Offen issues.open_title=Offen
issues.closed_title=Geschlossen issues.closed_title=Geschlossen
issues.num_comments=%d Kommentare issues.num_comments=%d Kommentare
issues.commented_at=`kommentierte <a href="#%s">%s</a>` issues.commented_at=`hat <a href="#%s">%s</a> kommentiert`
issues.delete_comment_confirm=Bist du sicher dass du diesen Kommentar löschen möchtest? issues.delete_comment_confirm=Bist du sicher dass du diesen Kommentar löschen möchtest?
issues.no_content=Hier gibt es bis jetzt noch keinen Inhalt. issues.no_content=Hier gibt es bis jetzt noch keinen Inhalt.
issues.close_issue=Schließen issues.close_issue=Schließen
@ -722,20 +722,20 @@ issues.subscribe=Abonnieren
issues.unsubscribe=Abbestellen issues.unsubscribe=Abbestellen
issues.tracker=Zeiterfassung issues.tracker=Zeiterfassung
issues.start_tracking_short=Start issues.start_tracking_short=Start
issues.start_tracking=Starte Zeiterfassungsstopuhr issues.start_tracking=Starte Zeiterfassung
issues.start_tracking_history=begann zu arbeiten %s issues.start_tracking_history=hat die Zeiterfassung %s gestartet
issues.tracking_already_started=`Du hast die Zeiterfassung bereits in <a href="%s">diesem Issue</a> gestartet!` issues.tracking_already_started=`Du hast die Zeiterfassung bereits in <a href="%s">diesem Issue</a> gestartet!`
issues.stop_tracking=Stopp issues.stop_tracking=Stopp
issues.stop_tracking_history=stoppte zu arbeiten %s issues.stop_tracking_history=hat die Zeiterfassung %s angehalten
issues.add_time=Zeit manuell hinzufügen issues.add_time=Zeit manuell hinzufügen
issues.add_time_short=Hinzufügen issues.add_time_short=Hinzufügen
issues.add_time_cancel=Abbrechen issues.add_time_cancel=Abbrechen
issues.add_time_history=fügte gearbeitete Zeit hinzu %s issues.add_time_history=hat %s gearbeitete Zeit hinzugefügt
issues.add_time_hours=Stunden issues.add_time_hours=Stunden
issues.add_time_minutes=Minuten issues.add_time_minutes=Minuten
issues.add_time_sum_to_small=Es wurde keine Zeit eingetragen issues.add_time_sum_to_small=Es wurde keine Zeit eingetragen
issues.cancel_tracking=Abbrechen issues.cancel_tracking=Abbrechen
issues.cancel_tracking_history=brach die Zeiterfassung ab %s issues.cancel_tracking_history=hat die Zeiterfassung %s abgebrochen
issues.time_spent_total=Insgesamt gearbeitete Zeit issues.time_spent_total=Insgesamt gearbeitete Zeit
pulls.desc=Pull-Requests helfen dir deinen Code zu überprüfen und neuen Code mit der Codebasis zusammenzuführen. pulls.desc=Pull-Requests helfen dir deinen Code zu überprüfen und neuen Code mit der Codebasis zusammenzuführen.
@ -1022,11 +1022,11 @@ settings.protected_branch_can_push_no=Du kannst nicht pushen
settings.branch_protection=Branch-Protection für <b>%s</b> settings.branch_protection=Branch-Protection für <b>%s</b>
settings.protect_this_branch=Diese Branch schützen settings.protect_this_branch=Diese Branch schützen
settings.protect_this_branch_desc=Verhindere Force-Pushes sowie Löschungen. settings.protect_this_branch_desc=Verhindere Force-Pushes sowie Löschungen.
settings.protect_whitelist_committers=Erlaube wer in diese Branch pushen kann settings.protect_whitelist_committers=Erlaube, wer in diese Branch pushen kann
settings.protect_whitelist_committers_desc=Füge Benutzer oder Teams zur Whitelist hinzu. Benutzer auf der Whitelist können Push-Restriktionen umgehen. settings.protect_whitelist_committers_desc=Füge Benutzer oder Teams zur Whitelist hinzu. Benutzer auf der Whitelist können Push-Restriktionen umgehen.
settings.protect_whitelist_users=Benutzer, die in diese Branch pushen können settings.protect_whitelist_users=Benutzer, die in diese Branch pushen dürfen
settings.protect_whitelist_search_users=Benutzer suchen settings.protect_whitelist_search_users=Benutzer suchen
settings.protect_whitelist_teams=Teams, deren Mitglieder in diese Branch pushen können. settings.protect_whitelist_teams=Teams, deren Mitglieder in diese Branch pushen dürfen
settings.protect_whitelist_search_teams=Teams suchen settings.protect_whitelist_search_teams=Teams suchen
settings.add_protected_branch=Schutz aktivieren settings.add_protected_branch=Schutz aktivieren
settings.delete_protected_branch=Schutz deaktivieren settings.delete_protected_branch=Schutz deaktivieren

View File

@ -936,6 +936,8 @@ settings.pulls.ignore_whitespace = Ignore changes in whitespace when checking co
settings.pulls.allow_merge_commits = Allow merge commits settings.pulls.allow_merge_commits = Allow merge commits
settings.pulls.allow_rebase_merge = Allow rebase to merge commits settings.pulls.allow_rebase_merge = Allow rebase to merge commits
settings.pulls.allow_squash_commits = Allow to squash commits before merging settings.pulls.allow_squash_commits = Allow to squash commits before merging
settings.admin_settings = Admin Settings
settings.admin_enable_health_check = Enable health checks (git fsck) for this repo
settings.danger_zone = Danger Zone settings.danger_zone = Danger Zone
settings.new_owner_has_same_repo = The new owner already has a repository with same name. Please choose another name. settings.new_owner_has_same_repo = The new owner already has a repository with same name. Please choose another name.
settings.convert = Convert To Regular Repository settings.convert = Convert To Regular Repository
@ -1054,6 +1056,10 @@ settings.protect_whitelist_users = Users who can push to this branch
settings.protect_whitelist_search_users = Search users settings.protect_whitelist_search_users = Search users
settings.protect_whitelist_teams = Teams whose members can push to this branch. settings.protect_whitelist_teams = Teams whose members can push to this branch.
settings.protect_whitelist_search_teams = Search teams settings.protect_whitelist_search_teams = Search teams
settings.protect_merge_whitelist_committers = Restrict who can merge pull requests to this branch
settings.protect_merge_whitelist_committers_desc = Add users or teams to this branch's merge whitelist. Only whitelisted users can merge pull requests to this branch. If not checked, anyone with write permissions can merge pull requests to this branch.
settings.protect_merge_whitelist_users = Users who can merge pull requests to this branch
settings.protect_merge_whitelist_teams = Teams whose members can merge pull requests to this branch.
settings.add_protected_branch=Enable protection settings.add_protected_branch=Enable protection
settings.delete_protected_branch=Disable protection settings.delete_protected_branch=Disable protection
settings.update_protect_branch_success = Branch %s protect options changed successfully. settings.update_protect_branch_success = Branch %s protect options changed successfully.

View File

@ -910,6 +910,8 @@ settings.pulls.ignore_whitespace=A whitespace-ek figyelmen kívül hagyása az
settings.pulls.allow_merge_commits=Egyesítési commit engedélyezése settings.pulls.allow_merge_commits=Egyesítési commit engedélyezése
settings.pulls.allow_rebase_merge=Rebase engedélyezése egyesítésnél settings.pulls.allow_rebase_merge=Rebase engedélyezése egyesítésnél
settings.pulls.allow_squash_commits=Squash engedélyezése egyesítés előtt settings.pulls.allow_squash_commits=Squash engedélyezése egyesítés előtt
settings.admin_settings=Rendszergazdai Beállítások
settings.admin_enable_health_check=Ellenőrzések (git fsck) engedélyezése
settings.danger_zone=Veszélyes terület settings.danger_zone=Veszélyes terület
settings.new_owner_has_same_repo=Az új tulajdonos már rendelkezik ilyen nevű tárolóval. Kérjük válasszon egy másik nevet. settings.new_owner_has_same_repo=Az új tulajdonos már rendelkezik ilyen nevű tárolóval. Kérjük válasszon egy másik nevet.
settings.convert=Hagyományos tárolóvá alakítás settings.convert=Hagyományos tárolóvá alakítás
@ -1028,6 +1030,10 @@ settings.protect_whitelist_users=Felhasználók, akik push-olhatnak az ágra
settings.protect_whitelist_search_users=Felhasználók keresése settings.protect_whitelist_search_users=Felhasználók keresése
settings.protect_whitelist_teams=Csoportok, melyeknek tagjai pusholhatnak az ágra. settings.protect_whitelist_teams=Csoportok, melyeknek tagjai pusholhatnak az ágra.
settings.protect_whitelist_search_teams=Csoportok keresése settings.protect_whitelist_search_teams=Csoportok keresése
settings.protect_merge_whitelist_committers=Korlátozza mely felhasználók egyesíthetnek más ágakat ebbe
settings.protect_merge_whitelist_committers_desc=Felhasználók vagy csapatok hozzáadása, akik egyesíthetnek más ágakat ebbe. Ha nincsen beállítva, bárki aki rendelkezik hozzáféréssel egyesíthet.
settings.protect_merge_whitelist_users=Felhasználók, akik egyesíthetnek más ágakat ebbe
settings.protect_merge_whitelist_teams=Korlátozza mely csapatok egyesíthetnek más ágakat ebbe
settings.add_protected_branch=Védelem engedélyezése settings.add_protected_branch=Védelem engedélyezése
settings.delete_protected_branch=Védelem letiltása settings.delete_protected_branch=Védelem letiltása
settings.update_protect_branch_success=%s ág védelme opciók sikeresen módosítva. settings.update_protect_branch_success=%s ág védelme opciók sikeresen módosítva.

View File

@ -169,9 +169,11 @@ repos=Repositories
users=Gebruikers users=Gebruikers
organizations=Organisaties organizations=Organisaties
search=Zoeken search=Zoeken
code=Code
repo_no_results=Er zijn geen overeenkomende repositories gevonden. repo_no_results=Er zijn geen overeenkomende repositories gevonden.
user_no_results=Er zijn geen overeenkomende gebruikers gevonden. user_no_results=Er zijn geen overeenkomende gebruikers gevonden.
org_no_results=Er zijn geen overeenkomende organisaties gevonden. org_no_results=Er zijn geen overeenkomende organisaties gevonden.
code_search_results=Zoekresultaten voor %s
[auth] [auth]
create_new_account=Account aanmaken create_new_account=Account aanmaken
@ -610,8 +612,11 @@ issues.new.closed_milestone=Gesloten mijlpalen
issues.new.assignee=Toegewezen aan issues.new.assignee=Toegewezen aan
issues.new.clear_assignee=Verwijder verantwoordelijke issues.new.clear_assignee=Verwijder verantwoordelijke
issues.new.no_assignee=Geen verantwoordelijke issues.new.no_assignee=Geen verantwoordelijke
issues.no_ref=Geen Branch/Tag gespecificeerd
issues.create=Maak probleem issues.create=Maak probleem
issues.new_label=Nieuw Label issues.new_label=Nieuw Label
issues.new_label_placeholder=Labelnaam…
issues.new_label_desc_placeholder=Omschrijving…
issues.create_label=Maak label issues.create_label=Maak label
issues.label_templates.title=Laad een vooraf gedefinieerde set labels issues.label_templates.title=Laad een vooraf gedefinieerde set labels
issues.label_templates.helper=Selecteer een labelset issues.label_templates.helper=Selecteer een labelset
@ -620,6 +625,7 @@ issues.change_milestone_at='mijlpaal bewerkt van <b>%s</b> <b>%s</b> %s'
issues.remove_milestone_at=' %s is verwijderd uit de <b>%s</b> mijlpaal' issues.remove_milestone_at=' %s is verwijderd uit de <b>%s</b> mijlpaal'
issues.deleted_milestone=` (verwijderd)` issues.deleted_milestone=` (verwijderd)`
issues.add_assignee_at=`was toegekend door <b>%s</b> %s` issues.add_assignee_at=`was toegekend door <b>%s</b> %s`
issues.change_title_at='titel aangepast van <b>%s</b> naar <b>%s</b> %s'
issues.open_tab=%d Open issues.open_tab=%d Open
issues.close_tab=%d gesloten issues.close_tab=%d gesloten
issues.filter_label=Label issues.filter_label=Label
@ -671,6 +677,7 @@ issues.edit=Bewerken
issues.cancel=Annuleren issues.cancel=Annuleren
issues.save=Opslaan issues.save=Opslaan
issues.label_title=Labelnaam issues.label_title=Labelnaam
issues.label_description=Label omschrijving
issues.label_color=Labelkleur issues.label_color=Labelkleur
issues.label_count=%d labels issues.label_count=%d labels
issues.label_open_issues=%d geopende problemen issues.label_open_issues=%d geopende problemen
@ -688,6 +695,7 @@ issues.attachment.open_tab=`Klik om "%s" in een nieuw tabblad te bekijken`
issues.attachment.download=`Klik om "%s" te downloaden` issues.attachment.download=`Klik om "%s" te downloaden`
issues.subscribe=Abonneren issues.subscribe=Abonneren
issues.unsubscribe=Uitschrijven issues.unsubscribe=Uitschrijven
issues.tracker=Tijd tracker
issues.start_tracking_short=Start issues.start_tracking_short=Start
issues.start_tracking=Start tijdregistratie issues.start_tracking=Start tijdregistratie
issues.start_tracking_history=`%s is begonnen` issues.start_tracking_history=`%s is begonnen`
@ -728,6 +736,8 @@ pulls.is_checking=Controle van conflicten is nog bezig, ververs deze pagina in e
pulls.can_auto_merge_desc=Dit pull-request kan automatisch samengevoegd worden. pulls.can_auto_merge_desc=Dit pull-request kan automatisch samengevoegd worden.
pulls.cannot_auto_merge_helper=Gelieve beide versies manueel samen te voegen om de conflicten op te lossen. pulls.cannot_auto_merge_helper=Gelieve beide versies manueel samen te voegen om de conflicten op te lossen.
pulls.merge_pull_request=Samenvoegen van pull verzoek pulls.merge_pull_request=Samenvoegen van pull verzoek
pulls.rebase_merge_pull_request=Rebase en Merge
pulls.squash_merge_pull_request=Squash en Merge
milestones.new=Nieuwe mijlpaal milestones.new=Nieuwe mijlpaal
milestones.open_tab=%d geopend milestones.open_tab=%d geopend
@ -783,6 +793,7 @@ activity.period.halfweekly=3 dagen
activity.period.weekly=1 week activity.period.weekly=1 week
activity.period.monthly=1 maand activity.period.monthly=1 maand
activity.overview=Overzicht activity.overview=Overzicht
activity.active_prs_count_n=<strong>%d</strong> Actieve Pull Requests
activity.title.user_1=%d gebruiker activity.title.user_1=%d gebruiker
activity.title.user_n=%d gebruikers activity.title.user_n=%d gebruikers
activity.title.prs_1=%d Pull aanvraag activity.title.prs_1=%d Pull aanvraag
@ -791,6 +802,7 @@ activity.title.prs_merged_by=%s samengevoegd door %s
activity.title.prs_opened_by=%s voorgesteld door %s activity.title.prs_opened_by=%s voorgesteld door %s
activity.merged_prs_label=Samengevoegd activity.merged_prs_label=Samengevoegd
activity.opened_prs_label=Voorgesteld activity.opened_prs_label=Voorgesteld
activity.active_issues_count_n=<strong>%d</strong> Actieve onderwerpen
activity.closed_issues_count_1=Gesloten problemen activity.closed_issues_count_1=Gesloten problemen
activity.closed_issues_count_n=Gesloten problemen activity.closed_issues_count_n=Gesloten problemen
activity.title.issues_1=%d Probleem activity.title.issues_1=%d Probleem
@ -809,6 +821,7 @@ activity.published_release_label=Gepubliceerd
search=Zoek search=Zoek
search.search_repo=Zoek repository search.search_repo=Zoek repository
search.results=Zoek resultaat voor "%s" in <a href="%s">%s</a>
settings=Instellingen settings=Instellingen
settings.options=Opties settings.options=Opties
@ -817,6 +830,7 @@ settings.collaboration.admin=Beheerder
settings.collaboration.write=Schrijf settings.collaboration.write=Schrijf
settings.collaboration.read=Lees settings.collaboration.read=Lees
settings.collaboration.undefined=Ongedefinieerd settings.collaboration.undefined=Ongedefinieerd
settings.hooks=Webhooks
settings.githooks=Git-hooks settings.githooks=Git-hooks
settings.basic_settings=Basis instellingen settings.basic_settings=Basis instellingen
settings.mirror_settings=Kopie Settings settings.mirror_settings=Kopie Settings
@ -835,7 +849,9 @@ settings.use_external_issue_tracker=Externe issuetracker gebruiken
settings.tracker_url_format=URL-formaat externe issuetracker settings.tracker_url_format=URL-formaat externe issuetracker
settings.tracker_issue_style.numeric=Nummeriek settings.tracker_issue_style.numeric=Nummeriek
settings.tracker_issue_style.alphanumeric=Alfanummeriek settings.tracker_issue_style.alphanumeric=Alfanummeriek
settings.enable_timetracker=Tijd tracker inschakelen
settings.pulls_desc=Schakel 'pull request' in om publieke bijdragen te mogelijk te maken settings.pulls_desc=Schakel 'pull request' in om publieke bijdragen te mogelijk te maken
settings.admin_settings=Beheerdersinstellingen
settings.danger_zone=Gevaren zone settings.danger_zone=Gevaren zone
settings.new_owner_has_same_repo=De nieuwe eigenaar heeft al een repository met deze naam settings.new_owner_has_same_repo=De nieuwe eigenaar heeft al een repository met deze naam
settings.convert=Converteren naar gewone repository settings.convert=Converteren naar gewone repository
@ -850,6 +866,7 @@ settings.transfer_form_title=Voer de volgende informatie in om de bewerking te b
settings.wiki_delete=Wiki gegevens verwijderen settings.wiki_delete=Wiki gegevens verwijderen
settings.wiki_delete_desc=Als U wiki informatie wist gaat deze onherroepelijk verloren. Weet u het zeker? settings.wiki_delete_desc=Als U wiki informatie wist gaat deze onherroepelijk verloren. Weet u het zeker?
settings.wiki_delete_notices_1=- Deze operatie wist de wiki voor %s en schakelt de wiki uit settings.wiki_delete_notices_1=- Deze operatie wist de wiki voor %s en schakelt de wiki uit
settings.confirm_wiki_delete=Wiki gegevens verwijderen
settings.wiki_deletion_success=De repository met wiki data is succesvol gewist. settings.wiki_deletion_success=De repository met wiki data is succesvol gewist.
settings.delete=Verwijder deze repository settings.delete=Verwijder deze repository
settings.delete_desc=Als u eenmaal een repository verwijderd is er geen weg terug. Gelieve zeker te zijn van uw acties. settings.delete_desc=Als u eenmaal een repository verwijderd is er geen weg terug. Gelieve zeker te zijn van uw acties.
@ -866,6 +883,7 @@ settings.delete_collaborator=Verwijderen
settings.collaborator_deletion=Verwijder Medewerker settings.collaborator_deletion=Verwijder Medewerker
settings.collaborator_deletion_desc=Deze gebruiker zal niet langer toegang hebben tot deze repository. Wilt U doorgaan? settings.collaborator_deletion_desc=Deze gebruiker zal niet langer toegang hebben tot deze repository. Wilt U doorgaan?
settings.remove_collaborator_success=medewerker is verwijderd. settings.remove_collaborator_success=medewerker is verwijderd.
settings.search_user_placeholder=Zoek gebruiker…
settings.org_not_allowed_to_be_collaborator=De organisatie kan niet toegevoegd worden als medewerker. settings.org_not_allowed_to_be_collaborator=De organisatie kan niet toegevoegd worden als medewerker.
settings.user_is_org_member=Gebruiker is lid van de organisatie die als een medewerker kan niet worden toegevoegd. settings.user_is_org_member=Gebruiker is lid van de organisatie die als een medewerker kan niet worden toegevoegd.
settings.add_webhook=Webhook toevoegen settings.add_webhook=Webhook toevoegen
@ -901,6 +919,7 @@ settings.event_pull_request=Pull request
settings.event_push=Push settings.event_push=Push
settings.event_push_desc=Git push naar een repository settings.event_push_desc=Git push naar een repository
settings.event_repository=Repository settings.event_repository=Repository
settings.event_repository_desc=Repository gemaakt of verwijderd
settings.active=Actief settings.active=Actief
settings.add_hook_success=Nieuwe webhook toegevoegd. settings.add_hook_success=Nieuwe webhook toegevoegd.
settings.update_webhook=Bewerk webhook settings.update_webhook=Bewerk webhook
@ -915,6 +934,7 @@ settings.slack_channel=Slack kanaal
settings.deploy_keys=Installeer sleutels settings.deploy_keys=Installeer sleutels
settings.add_deploy_key=Toevoegen deploy sleutel settings.add_deploy_key=Toevoegen deploy sleutel
settings.deploy_key_desc=Sleutels voor uitrol hebben enkel leesrechten. Ze zijn niet dezelfde als de SSH sleutels van persoonlijke accounts. settings.deploy_key_desc=Sleutels voor uitrol hebben enkel leesrechten. Ze zijn niet dezelfde als de SSH sleutels van persoonlijke accounts.
settings.is_writable=Schrijftoegang toestaan
settings.no_deploy_keys=U hebt nog geen deploy sleutels toegevoegd. settings.no_deploy_keys=U hebt nog geen deploy sleutels toegevoegd.
settings.title=Titel settings.title=Titel
settings.deploy_key_content=Inhoud settings.deploy_key_content=Inhoud
@ -926,11 +946,15 @@ settings.deploy_key_deletion_success=Deploy sleutel werd met succes verwijderd!
settings.branches=Branches settings.branches=Branches
settings.protected_branch=Branch bescherming settings.protected_branch=Branch bescherming
settings.protected_branch_can_push=Push toestaan? settings.protected_branch_can_push=Push toestaan?
settings.protected_branch_can_push_no=U mag niet pushen
settings.protect_this_branch=Bescherm deze branch
settings.protect_whitelist_users=Gebruikers die mogen pushen naar deze branch
settings.protect_whitelist_search_users=Zoek gebruikers settings.protect_whitelist_search_users=Zoek gebruikers
settings.protect_whitelist_search_teams=Zoek teams settings.protect_whitelist_search_teams=Zoek teams
settings.add_protected_branch=Bescherming aanzetten settings.add_protected_branch=Bescherming aanzetten
settings.delete_protected_branch=Bescherming uitzetten settings.delete_protected_branch=Bescherming uitzetten
settings.remove_protected_branch_success=%s is ontgrendeld settings.remove_protected_branch_success=%s is ontgrendeld
settings.choose_branch=Kies een branch…
settings.no_protected_branch=Er zijn geen beschermde branches settings.no_protected_branch=Er zijn geen beschermde branches
diff.browse_source=Bladeren bron diff.browse_source=Bladeren bron
@ -959,6 +983,7 @@ release.title=Titel
release.content=Inhoud release.content=Inhoud
release.write=Schrijf release.write=Schrijf
release.preview=Voorbeeld release.preview=Voorbeeld
release.loading=Laden…
release.prerelease_desc=Dit is een beta-versie release.prerelease_desc=Dit is een beta-versie
release.prerelease_helper=Wij wijzen u erop dat deze release is niet geschikt voor productie doeleinden. release.prerelease_helper=Wij wijzen u erop dat deze release is niet geschikt voor productie doeleinden.
release.cancel=Annuleren release.cancel=Annuleren
@ -983,6 +1008,7 @@ branch.deletion_success=%s is verwijderd.
branch.deletion_failed=%s verwijderen is mislukt. branch.deletion_failed=%s verwijderen is mislukt.
branch.create_branch=Maak branch <strong>%s</strong> branch.create_branch=Maak branch <strong>%s</strong>
branch.create_from=van '%s' branch.create_from=van '%s'
branch.create_success=Branch '%s' is met succes aangemaakt!
branch.deleted_by=Verwijderd door %s branch.deleted_by=Verwijderd door %s
[org] [org]
@ -995,6 +1021,8 @@ people=Mensen
teams=Teams teams=Teams
lower_members=leden lower_members=leden
lower_repositories=repositories lower_repositories=repositories
create_new_team=Nieuw team
create_team=Maak team
org_desc=Omschrijving org_desc=Omschrijving
team_name=Teamnaam team_name=Teamnaam
team_desc=Omschrijving team_desc=Omschrijving
@ -1054,6 +1082,7 @@ teams.read_permission_desc=Dit team heeft <strong>Lees</strong> rechten : leden
teams.write_permission_desc=Dit team heeft <strong>Schrijf</strong> rechten : leden kunnen repositories lezen en push aanvragen verwerken. teams.write_permission_desc=Dit team heeft <strong>Schrijf</strong> rechten : leden kunnen repositories lezen en push aanvragen verwerken.
teams.admin_permission_desc=Dit team heeft <strong>Beheerders</strong> rechten : leden kunnen repositories lezen en push aanvragen verwerken en medewerkers toevoegen. teams.admin_permission_desc=Dit team heeft <strong>Beheerders</strong> rechten : leden kunnen repositories lezen en push aanvragen verwerken en medewerkers toevoegen.
teams.repositories=Teamrepositories teams.repositories=Teamrepositories
teams.search_repo_placeholder=Repository zoeken…
teams.add_team_repository=Nieuwe teamrepositorie aanmaken teams.add_team_repository=Nieuwe teamrepositorie aanmaken
teams.remove_repo=Verwijder teams.remove_repo=Verwijder
teams.add_nonexistent_repo=De opslagplaats die u probeert toe te voegen bestaat niet: maak deze eerst aan. teams.add_nonexistent_repo=De opslagplaats die u probeert toe te voegen bestaat niet: maak deze eerst aan.
@ -1062,6 +1091,7 @@ teams.add_nonexistent_repo=De opslagplaats die u probeert toe te voegen bestaat
dashboard=Overzicht dashboard=Overzicht
users=Gebruikers users=Gebruikers
organizations=Organisaties organizations=Organisaties
repositories=Repositories
authentication=Authenticaties authentication=Authenticaties
config=Configuratie config=Configuratie
notices=Systeem aankondigingen notices=Systeem aankondigingen
@ -1115,6 +1145,7 @@ dashboard.total_gc_pause=Totaal GC verwerkingstijd
dashboard.last_gc_pause=Laatste GC verwerkingstijd dashboard.last_gc_pause=Laatste GC verwerkingstijd
dashboard.gc_times=GC verwerkingen dashboard.gc_times=GC verwerkingen
users.user_manage_panel=Gebruikersbeheer paneel
users.new_account=Nieuw account aanmaken users.new_account=Nieuw account aanmaken
users.name=Naam users.name=Naam
users.activated=Geactiveerd users.activated=Geactiveerd
@ -1246,6 +1277,7 @@ config.mail_notify=E-mailnotificaties
config.disable_key_size_check=Controle op key-lengte uitschakelen config.disable_key_size_check=Controle op key-lengte uitschakelen
config.enable_captcha=CAPTCHA inschakelen config.enable_captcha=CAPTCHA inschakelen
config.active_code_lives=Actieve Code leven config.active_code_lives=Actieve Code leven
config.default_enable_timetracking=Time tracking standaard inschakelen
config.no_reply_address=No-reply emailadres config.no_reply_address=No-reply emailadres
config.webhook_config=Webhook configuratie config.webhook_config=Webhook configuratie
@ -1261,6 +1293,7 @@ config.mailer_user=Gebruiker
config.mailer_use_sendmail=Gebruik Sendmail config.mailer_use_sendmail=Gebruik Sendmail
config.mailer_sendmail_path=Sendmail pad config.mailer_sendmail_path=Sendmail pad
config.send_test_mail=Testbericht verzenden config.send_test_mail=Testbericht verzenden
config.test_mail_failed=Verzenden van een testmail naar '%s' is mislukt: %v
config.test_mail_sent=Test-email is verstuurd naar '%s'. config.test_mail_sent=Test-email is verstuurd naar '%s'.
config.oauth_config=OAuth-configuratie config.oauth_config=OAuth-configuratie
@ -1366,8 +1399,10 @@ no_unread=Je hebt geen ongelezen meldingen.
no_read=Je hebt geen gelezen meldingen. no_read=Je hebt geen gelezen meldingen.
mark_as_read=Markeer als gelezen mark_as_read=Markeer als gelezen
mark_as_unread=Markeer als ongelezen mark_as_unread=Markeer als ongelezen
mark_all_as_read=Markeer alles als gelezen
[gpg] [gpg]
error.generate_hash=Genereren van commit hash mislukt
error.no_committer_account=Geen account gekoppeld aan de committers e-mail error.no_committer_account=Geen account gekoppeld aan de committers e-mail
error.no_gpg_keys_found=Geen bekende sleutel gevonden voor deze handtekening in de database error.no_gpg_keys_found=Geen bekende sleutel gevonden voor deze handtekening in de database

View File

@ -910,6 +910,8 @@ settings.pulls.ignore_whitespace=Игнорировать незначащие
settings.pulls.allow_merge_commits=Разрешить коммиты слияния settings.pulls.allow_merge_commits=Разрешить коммиты слияния
settings.pulls.allow_rebase_merge=Разрешить rebase-слияние settings.pulls.allow_rebase_merge=Разрешить rebase-слияние
settings.pulls.allow_squash_commits=Разрешить объединять коммиты перед слиянием settings.pulls.allow_squash_commits=Разрешить объединять коммиты перед слиянием
settings.admin_settings=Административные настройки
settings.admin_enable_health_check=Выполнять проверки целостности этого репозитория (git fsck)
settings.danger_zone=Опасная зона settings.danger_zone=Опасная зона
settings.new_owner_has_same_repo=У нового владельца уже есть хранилище с таким названием. settings.new_owner_has_same_repo=У нового владельца уже есть хранилище с таким названием.
settings.convert=Преобразовать в обычный репозиторий settings.convert=Преобразовать в обычный репозиторий
@ -1028,6 +1030,10 @@ settings.protect_whitelist_users=Пользователи которые мог
settings.protect_whitelist_search_users=Поиск пользователей settings.protect_whitelist_search_users=Поиск пользователей
settings.protect_whitelist_teams=Команды, члены которых могут делать push в эту ветку. settings.protect_whitelist_teams=Команды, члены которых могут делать push в эту ветку.
settings.protect_whitelist_search_teams=Поиск команд settings.protect_whitelist_search_teams=Поиск команд
settings.protect_merge_whitelist_committers=Ограничить право на принятие Pull Request'ов в эту ветку списком
settings.protect_merge_whitelist_committers_desc=Вы можете добавлять пользователей или целые команды в "белый" список этой ветки. Только присутствующие в списке смогут принимать Pull Request'ы. В противном случае любой с правами на запись в репозиторий будет обладать такой возможностью.
settings.protect_merge_whitelist_users=Пользователи с правом на принятие Pull Request'ов в эту ветку
settings.protect_merge_whitelist_teams=Команды, члены которых обладают правом на принятие Pull Request'ов в эту ветку.
settings.add_protected_branch=Включить защиту settings.add_protected_branch=Включить защиту
settings.delete_protected_branch=Отключить защиту settings.delete_protected_branch=Отключить защиту
settings.update_protect_branch_success=Настройки защиты ветки %s были успешно изменены. settings.update_protect_branch_success=Настройки защиты ветки %s были успешно изменены.

View File

@ -1664,8 +1664,11 @@ function selectRange($list, $select, $from) {
} }
$(function () { $(function () {
if ($('.user.signin').length > 0) return; // Warn users that try to leave a page after entering data into a form.
$('form').areYouSure(); // Except on sign-in pages, and for forms marked as 'ignore-dirty'.
if ($('.user.signin').length === 0) {
$('form:not(.ignore-dirty)').areYouSure();
}
// Parse SSH Key // Parse SSH Key
$("#ssh-key-content").on('change paste keyup',function(){ $("#ssh-key-content").on('change paste keyup',function(){

View File

@ -5,11 +5,11 @@
package repo package repo
import ( import (
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/routers/api/v1/convert" "code.gitea.io/gitea/routers/api/v1/convert"
api "code.gitea.io/sdk/gitea"
) )
// GetBranch get a branch of a repository // GetBranch get a branch of a repository

View File

@ -5,10 +5,10 @@
package repo package repo
import ( import (
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
api "code.gitea.io/sdk/gitea"
) )
// ListCollaborators list a repository's collaborators // ListCollaborators list a repository's collaborators

View File

@ -5,11 +5,11 @@
package repo package repo
import ( import (
"code.gitea.io/git"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/routers/repo" "code.gitea.io/gitea/routers/repo"
"code.gitea.io/git"
) )
// GetRawFile get a file by path on a repository // GetRawFile get a file by path on a repository

View File

@ -5,11 +5,11 @@
package repo package repo
import ( import (
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/routers/api/v1/utils" "code.gitea.io/gitea/routers/api/v1/utils"
api "code.gitea.io/sdk/gitea"
) )
// ListForks list a repository's forks // ListForks list a repository's forks

View File

@ -5,12 +5,12 @@
package repo package repo
import ( import (
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/routers/api/v1/convert" "code.gitea.io/gitea/routers/api/v1/convert"
"code.gitea.io/gitea/routers/api/v1/utils" "code.gitea.io/gitea/routers/api/v1/utils"
api "code.gitea.io/sdk/gitea"
) )
// ListHooks list all hooks of a repository // ListHooks list all hooks of a repository

View File

@ -9,13 +9,13 @@ import (
"net/http" "net/http"
"strings" "strings"
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/indexer" "code.gitea.io/gitea/modules/indexer"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
api "code.gitea.io/sdk/gitea"
) )
// ListIssues list the issues of a repository // ListIssues list the issues of a repository

View File

@ -7,10 +7,10 @@ package repo
import ( import (
"time" "time"
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
api "code.gitea.io/sdk/gitea"
) )
// ListIssueComments list all the comments of an issue // ListIssueComments list all the comments of an issue

View File

@ -5,10 +5,10 @@
package repo package repo
import ( import (
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
api "code.gitea.io/sdk/gitea"
) )
// ListIssueLabels list all the labels of an issue // ListIssueLabels list all the labels of an issue

View File

@ -7,6 +7,7 @@ package repo
import ( import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
api "code.gitea.io/sdk/gitea" api "code.gitea.io/sdk/gitea"
) )

View File

@ -7,12 +7,12 @@ package repo
import ( import (
"fmt" "fmt"
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers/api/v1/convert" "code.gitea.io/gitea/routers/api/v1/convert"
api "code.gitea.io/sdk/gitea"
) )
func composeDeployKeysAPILink(repoPath string) string { func composeDeployKeysAPILink(repoPath string) string {

View File

@ -7,10 +7,10 @@ package repo
import ( import (
"strconv" "strconv"
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
api "code.gitea.io/sdk/gitea"
) )
// ListLabels list all the labels of a repository // ListLabels list all the labels of a repository

View File

@ -7,11 +7,11 @@ package repo
import ( import (
"time" "time"
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
api "code.gitea.io/sdk/gitea"
) )
// ListMilestones list all the milestones for a repository // ListMilestones list all the milestones for a repository

View File

@ -5,10 +5,10 @@
package repo package repo
import ( import (
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
api "code.gitea.io/sdk/gitea"
) )
// GetRelease get a single release of a repository // GetRelease get a single release of a repository

View File

@ -5,13 +5,15 @@
package repo package repo
import ( import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/sdk/gitea"
"errors" "errors"
"net/http" "net/http"
"strings" "strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/sdk/gitea"
) )
// GetReleaseAttachment gets a single attachment of the release // GetReleaseAttachment gets a single attachment of the release

View File

@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/routers/api/v1/convert" "code.gitea.io/gitea/routers/api/v1/convert"
api "code.gitea.io/sdk/gitea" api "code.gitea.io/sdk/gitea"
) )

View File

@ -5,9 +5,9 @@
package repo package repo
import ( import (
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
api "code.gitea.io/sdk/gitea"
) )
// ListStargazers list a repository's stargazers // ListStargazers list a repository's stargazers

View File

@ -9,6 +9,7 @@ import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
api "code.gitea.io/sdk/gitea" api "code.gitea.io/sdk/gitea"
) )

View File

@ -5,9 +5,9 @@
package repo package repo
import ( import (
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
api "code.gitea.io/sdk/gitea"
) )
// ListSubscribers list a repo's subscribers (i.e. watchers) // ListSubscribers list a repo's subscribers (i.e. watchers)

View File

@ -184,33 +184,33 @@ func HTTP(ctx *context.Context) {
return return
} }
} }
}
if !isPublicPull { if !isPublicPull {
has, err := models.HasAccess(authUser.ID, repo, accessMode) has, err := models.HasAccess(authUser.ID, repo, accessMode)
if err != nil { if err != nil {
ctx.ServerError("HasAccess", err) ctx.ServerError("HasAccess", err)
return return
} else if !has { } else if !has {
if accessMode == models.AccessModeRead { if accessMode == models.AccessModeRead {
has, err = models.HasAccess(authUser.ID, repo, models.AccessModeWrite) has, err = models.HasAccess(authUser.ID, repo, models.AccessModeWrite)
if err != nil { if err != nil {
ctx.ServerError("HasAccess2", err) ctx.ServerError("HasAccess2", err)
return return
} else if !has { } else if !has {
ctx.HandleText(http.StatusForbidden, "User permission denied")
return
}
} else {
ctx.HandleText(http.StatusForbidden, "User permission denied") ctx.HandleText(http.StatusForbidden, "User permission denied")
return return
} }
} } else {
ctx.HandleText(http.StatusForbidden, "User permission denied")
if !isPull && repo.IsMirror {
ctx.HandleText(http.StatusForbidden, "mirror repository is read-only")
return return
} }
} }
if !isPull && repo.IsMirror {
ctx.HandleText(http.StatusForbidden, "mirror repository is read-only")
return
}
} }
if !repo.CheckUnitUser(authUser.ID, authUser.IsAdmin, unitType) { if !repo.CheckUnitUser(authUser.ID, authUser.IsAdmin, unitType) {

View File

@ -112,7 +112,7 @@ func Issues(ctx *context.Context) {
viewType := ctx.Query("type") viewType := ctx.Query("type")
sortType := ctx.Query("sort") sortType := ctx.Query("sort")
types := []string{"all", "assigned", "created_by", "mentioned"} types := []string{"all", "your_repositories", "assigned", "created_by", "mentioned"}
if !com.IsSliceContainsStr(types, viewType) { if !com.IsSliceContainsStr(types, viewType) {
viewType = "all" viewType = "all"
} }

View File

@ -32,7 +32,7 @@ func TestInitializeLabels(t *testing.T) {
ctx := test.MockContext(t, "user2/repo1/labels/initialize") ctx := test.MockContext(t, "user2/repo1/labels/initialize")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 2) test.LoadRepo(t, ctx, 2)
InitializeLabels(ctx, auth.InitializeLabelsForm{"Default"}) InitializeLabels(ctx, auth.InitializeLabelsForm{TemplateName: "Default"})
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status()) assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
models.AssertExistsAndLoadBean(t, &models.Label{ models.AssertExistsAndLoadBean(t, &models.Label{
RepoID: 2, RepoID: 2,

View File

@ -230,6 +230,24 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success")) ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
ctx.Redirect(ctx.Repo.RepoLink + "/settings") ctx.Redirect(ctx.Repo.RepoLink + "/settings")
case "admin":
if !ctx.User.IsAdmin {
ctx.Error(403)
return
}
if repo.IsFsckEnabled != form.EnableHealthCheck {
repo.IsFsckEnabled = form.EnableHealthCheck
if err := models.UpdateRepository(repo, false); err != nil {
ctx.ServerError("UpdateRepository", err)
return
}
log.Trace("Repository admin settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
}
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
case "convert": case "convert":
if !ctx.Repo.IsOwner() { if !ctx.Repo.IsOwner() {
ctx.Error(404) ctx.Error(404)

View File

@ -98,7 +98,7 @@ func SettingsProtectedBranch(c *context.Context) {
return return
} }
c.Data["Title"] = c.Tr("repo.settings.protected_branches") + " - " + branch c.Data["Title"] = c.Tr("repo.settings.protected_branch") + " - " + branch
c.Data["PageIsSettingsBranches"] = true c.Data["PageIsSettingsBranches"] = true
protectBranch, err := models.GetProtectedBranchBy(c.Repo.Repository.ID, branch) protectBranch, err := models.GetProtectedBranchBy(c.Repo.Repository.ID, branch)
@ -123,6 +123,7 @@ func SettingsProtectedBranch(c *context.Context) {
} }
c.Data["Users"] = users c.Data["Users"] = users
c.Data["whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.WhitelistUserIDs), ",") c.Data["whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.WhitelistUserIDs), ",")
c.Data["merge_whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.MergeWhitelistUserIDs), ",")
if c.Repo.Owner.IsOrganization() { if c.Repo.Owner.IsOrganization() {
teams, err := c.Repo.Owner.TeamsWithAccessToRepo(c.Repo.Repository.ID, models.AccessModeWrite) teams, err := c.Repo.Owner.TeamsWithAccessToRepo(c.Repo.Repository.ID, models.AccessModeWrite)
@ -132,6 +133,7 @@ func SettingsProtectedBranch(c *context.Context) {
} }
c.Data["Teams"] = teams c.Data["Teams"] = teams
c.Data["whitelist_teams"] = strings.Join(base.Int64sToStrings(protectBranch.WhitelistTeamIDs), ",") c.Data["whitelist_teams"] = strings.Join(base.Int64sToStrings(protectBranch.WhitelistTeamIDs), ",")
c.Data["merge_whitelist_teams"] = strings.Join(base.Int64sToStrings(protectBranch.MergeWhitelistTeamIDs), ",")
} }
c.Data["Branch"] = protectBranch c.Data["Branch"] = protectBranch
@ -166,7 +168,10 @@ func SettingsProtectedBranchPost(ctx *context.Context, f auth.ProtectBranchForm)
protectBranch.EnableWhitelist = f.EnableWhitelist protectBranch.EnableWhitelist = f.EnableWhitelist
whitelistUsers, _ := base.StringsToInt64s(strings.Split(f.WhitelistUsers, ",")) whitelistUsers, _ := base.StringsToInt64s(strings.Split(f.WhitelistUsers, ","))
whitelistTeams, _ := base.StringsToInt64s(strings.Split(f.WhitelistTeams, ",")) whitelistTeams, _ := base.StringsToInt64s(strings.Split(f.WhitelistTeams, ","))
err = models.UpdateProtectBranch(ctx.Repo.Repository, protectBranch, whitelistUsers, whitelistTeams) protectBranch.EnableMergeWhitelist = f.EnableMergeWhitelist
mergeWhitelistUsers, _ := base.StringsToInt64s(strings.Split(f.MergeWhitelistUsers, ","))
mergeWhitelistTeams, _ := base.StringsToInt64s(strings.Split(f.MergeWhitelistTeams, ","))
err = models.UpdateProtectBranch(ctx.Repo.Repository, protectBranch, whitelistUsers, whitelistTeams, mergeWhitelistUsers, mergeWhitelistTeams)
if err != nil { if err != nil {
ctx.ServerError("UpdateProtectBranch", err) ctx.ServerError("UpdateProtectBranch", err)
return return

View File

@ -17,7 +17,7 @@
</div> </div>
</div> </div>
</div> </div>
<form class="ui form" style="max-width: 90%"> <form class="ui form ignore-dirty" style="max-width: 90%">
<div class="ui fluid action input"> <div class="ui fluid action input">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus> <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
<button class="ui blue button">{{.i18n.Tr "explore.search"}}</button> <button class="ui blue button">{{.i18n.Tr "explore.search"}}</button>

View File

@ -187,7 +187,7 @@
{{end}} {{end}}
<dt>{{.i18n.Tr "admin.config.mailer_user"}}</dt> <dt>{{.i18n.Tr "admin.config.mailer_user"}}</dt>
<dd>{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}</dd><br> <dd>{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}</dd><br>
<form class="ui form" action="{{AppSubUrl}}/admin/config/test_mail" method="post"> <form class="ui form ignore-dirty" action="{{AppSubUrl}}/admin/config/test_mail" method="post">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<div class="inline field ui left"> <div class="inline field ui left">
<div class="ui input"> <div class="ui input">

View File

@ -2,7 +2,7 @@
<div class="explore users"> <div class="explore users">
{{template "explore/navbar" .}} {{template "explore/navbar" .}}
<div class="ui container"> <div class="ui container">
<form class="ui form" style="max-width: 100%"> <form class="ui form ignore-dirty" style="max-width: 100%">
<div class="ui fluid action input"> <div class="ui fluid action input">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus> <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
<input type="hidden" name="tab" value="{{$.TabName}}"> <input type="hidden" name="tab" value="{{$.TabName}}">

View File

@ -15,7 +15,7 @@
</div> </div>
</div> </div>
</div> </div>
<form class="ui form" style="max-width: 90%"> <form class="ui form ignore-dirty" style="max-width: 90%">
<div class="ui fluid action input"> <div class="ui fluid action input">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus> <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
<input type="hidden" name="tab" value="{{$.TabName}}"> <input type="hidden" name="tab" value="{{$.TabName}}">

View File

@ -13,7 +13,7 @@
<div class="ui red message"> <div class="ui red message">
<p class="text left"><i class="octicon octicon-alert"></i> {{.i18n.Tr "org.settings.delete_prompt" | Str2html}}</p> <p class="text left"><i class="octicon octicon-alert"></i> {{.i18n.Tr "org.settings.delete_prompt" | Str2html}}</p>
</div> </div>
<form class="ui form" id="delete-form" action="{{.Link}}" method="post"> <form class="ui form ignore-dirty" id="delete-form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<input class="fake" type="password"> <input class="fake" type="password">
<div class="inline required field {{if .Err_Password}}error{{end}}"> <div class="inline required field {{if .Err_Password}}error{{end}}">

View File

@ -5,7 +5,7 @@
</div> </div>
<div class="ten wide right aligned column"> <div class="ten wide right aligned column">
{{if .PageIsCommits}} {{if .PageIsCommits}}
<form action="{{.RepoLink}}/commits/{{.BranchNameSubURL}}/search"> <form class="ignore-dirty" action="{{.RepoLink}}/commits/{{.BranchNameSubURL}}/search">
<div class="ui tiny search input"> <div class="ui tiny search input">
<input name="q" placeholder="{{.i18n.Tr "repo.commits.search"}}" value="{{.Keyword}}" autofocus> <input name="q" placeholder="{{.i18n.Tr "repo.commits.search"}}" value="{{.Keyword}}" autofocus>
</div> </div>

View File

@ -10,7 +10,7 @@
</div> </div>
{{if .RepoSearchEnabled}} {{if .RepoSearchEnabled}}
<div class="ui repo-search"> <div class="ui repo-search">
<form class="ui form" action="{{.RepoLink}}/search" method="get"> <form class="ui form ignore-dirty" action="{{.RepoLink}}/search" method="get">
<div class="field"> <div class="field">
<div class="ui action input"> <div class="ui action input">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "repo.search.search_repo"}}"> <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "repo.search.search_repo"}}">

View File

@ -1,4 +1,4 @@
<form class="ui form"> <form class="ui form ignore-dirty">
<div class="ui fluid action input"> <div class="ui fluid action input">
<input type="hidden" name="type" value="{{$.ViewType}}"/> <input type="hidden" name="type" value="{{$.ViewType}}"/>
<input type="hidden" name="state" value="{{$.State}}"/> <input type="hidden" name="state" value="{{$.State}}"/>

View File

@ -79,7 +79,7 @@
<li> <li>
<a target="_blank" rel="noopener" href="{{AppSubUrl}}/attachments/{{.UUID}}"> <a target="_blank" rel="noopener" href="{{AppSubUrl}}/attachments/{{.UUID}}">
<strong><span class="ui image octicon octicon-package" title='{{.Name}}'></span> {{.Name}}</strong> <strong><span class="ui image octicon octicon-package" title='{{.Name}}'></span> {{.Name}}</strong>
<span class="ui text grey right">{{.MustSize | FileSize}}</span> <span class="ui text grey right">{{.Size | FileSize}}</span>
</a> </a>
</li> </li>
{{end}} {{end}}

View File

@ -3,7 +3,7 @@
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container"> <div class="ui container">
<div class="ui repo-search"> <div class="ui repo-search">
<form class="ui form" method="get"> <form class="ui form ignore-dirty" method="get">
<div class="ui fluid action input"> <div class="ui fluid action input">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "repo.search.search_repo"}}"> <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "repo.search.search_repo"}}">
<button class="ui button" type="submit"> <button class="ui button" type="submit">

View File

@ -242,6 +242,29 @@
</form> </form>
</div> </div>
{{if .IsAdmin}}
<h4 class="ui top attached header">
{{.i18n.Tr "repo.settings.admin_settings"}}
</h4>
<div class="ui attached segment">
<form class="ui form" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="admin">
<div class="field">
<div class="ui checkbox">
<input name="enable_health_check" type="checkbox" {{if .Repository.IsFsckEnabled}}checked{{end}}>
<label>{{.i18n.Tr "repo.settings.admin_enable_health_check"}}</label>
</div>
</div>
<div class="ui divider"></div>
<div class="field">
<button class="ui green button">{{$.i18n.Tr "repo.settings.update_settings"}}</button>
</div>
</form>
</div>
{{end}}
{{if .IsRepositoryOwner}} {{if .IsRepositoryOwner}}
<h4 class="ui top attached warning header"> <h4 class="ui top attached warning header">
{{.i18n.Tr "repo.settings.danger_zone"}} {{.i18n.Tr "repo.settings.danger_zone"}}

View File

@ -60,6 +60,49 @@
</div> </div>
{{end}} {{end}}
</div> </div>
<div class="field">
<div class="ui checkbox">
<input class="enable-whitelist" name="enable_merge_whitelist" type="checkbox" data-target="#merge_whitelist_box" {{if .Branch.EnableMergeWhitelist}}checked{{end}}>
<label>{{.i18n.Tr "repo.settings.protect_merge_whitelist_committers"}}</label>
<p class="help">{{.i18n.Tr "repo.settings.protect_merge_whitelist_committers_desc"}}</p>
</div>
</div>
<div id="merge_whitelist_box" class="fields {{if not .Branch.EnableMergeWhitelist}}disabled{{end}}">
<div class="whitelist field">
<label>{{.i18n.Tr "repo.settings.protect_merge_whitelist_users"}}</label>
<div class="ui multiple search selection dropdown">
<input type="hidden" name="merge_whitelist_users" value="{{.merge_whitelist_users}}">
<div class="default text">{{.i18n.Tr "repo.settings.protect_whitelist_search_users"}}</div>
<div class="menu">
{{range .Users}}
<div class="item" data-value="{{.ID}}">
<img class="ui mini image" src="{{.RelAvatarLink}}">
{{.Name}}
</div>
{{end}}
</div>
</div>
</div>
{{if .Owner.IsOrganization}}
<br>
<div class="whitelist field">
<label>{{.i18n.Tr "repo.settings.protect_merge_whitelist_teams"}}</label>
<div class="ui multiple search selection dropdown">
<input type="hidden" name="merge_whitelist_teams" value="{{.merge_whitelist_teams}}">
<div class="default text">{{.i18n.Tr "repo.settings.protect_whitelist_search_teams"}}</div>
<div class="menu">
{{range .Teams}}
<div class="item" data-value="{{.ID}}">
<i class="octicon octicon-jersey"></i>
{{.Name}}
</div>
{{end}}
</div>
</div>
</div>
{{end}}
</div>
</div> </div>
<div class="ui divider"></div> <div class="ui divider"></div>

View File

@ -2,7 +2,7 @@
<div class="user activate"> <div class="user activate">
<div class="ui middle very relaxed page grid"> <div class="ui middle very relaxed page grid">
<div class="column"> <div class="column">
<form class="ui form" action="{{AppSubUrl}}/user/activate" method="post"> <form class="ui form ignore-dirty" action="{{AppSubUrl}}/user/activate" method="post">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<h2 class="ui top attached header"> <h2 class="ui top attached header">
{{.i18n.Tr "auth.active_your_account"}} {{.i18n.Tr "auth.active_your_account"}}

View File

@ -2,7 +2,7 @@
<div class="user forgot password"> <div class="user forgot password">
<div class="ui middle very relaxed page grid"> <div class="ui middle very relaxed page grid">
<div class="column"> <div class="column">
<form class="ui form" action="{{.Link}}" method="post"> <form class="ui form ignore-dirty" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<h2 class="ui top attached header"> <h2 class="ui top attached header">
{{.i18n.Tr "auth.forgot_password_title"}} {{.i18n.Tr "auth.forgot_password_title"}}

View File

@ -2,7 +2,7 @@
<div class="user reset password"> <div class="user reset password">
<div class="ui middle very relaxed page grid"> <div class="ui middle very relaxed page grid">
<div class="column"> <div class="column">
<form class="ui form" action="{{.Link}}" method="post"> <form class="ui form ignore-dirty" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<input name="code" type="hidden" value="{{.Code}}"> <input name="code" type="hidden" value="{{.Code}}">
<h2 class="ui top attached header"> <h2 class="ui top attached header">

View File

@ -38,7 +38,7 @@
{{.i18n.Tr "settings.generate_new_token"}} {{.i18n.Tr "settings.generate_new_token"}}
</h4> </h4>
<div class="ui attached segment"> <div class="ui attached segment">
<form class="ui form" action="{{.Link}}" method="post"> <form class="ui form ignore-dirty" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<p>{{.i18n.Tr "settings.new_token_desc"}}</p> <p>{{.i18n.Tr "settings.new_token_desc"}}</p>
<div class="field {{if .Err_Name}}error{{end}}"> <div class="field {{if .Err_Name}}error{{end}}">

View File

@ -10,7 +10,7 @@
<div class="ui red message"> <div class="ui red message">
<p class="text left"><i class="octicon octicon-alert"></i> {{.i18n.Tr "settings.delete_prompt" | Str2html}}</p> <p class="text left"><i class="octicon octicon-alert"></i> {{.i18n.Tr "settings.delete_prompt" | Str2html}}</p>
</div> </div>
<form class="ui form" id="delete-form" action="{{.Link}}" method="post"> <form class="ui form ignore-dirty" id="delete-form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<input class="fake" type="password"> <input class="fake" type="password">
<div class="required field {{if .Err_Password}}error{{end}}"> <div class="required field {{if .Err_Password}}error{{end}}">