# 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
; For iterate buffer, default is 50
ITERATE_BUFFER_SIZE = 50
; Show the database generated SQL
LOG_SQL = true
[indexer]
ISSUE_INDEXER_PATH = indexers/issues.bleve

View File

@ -1,5 +1,7 @@
#!/bin/bash
/usr/sbin/update-ca-certificates
if [ ! -d /data/git/.ssh ]; then
mkdir -p /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.
- `SSL_MODE`: **disable**: For PostgreSQL only.
- `PATH`: **data/gitea.db**: For SQLite3 only, the database file path.
- `LOG_SQL`: **true**: Log the executed SQL.
## Indexer (`indexer`)

View File

@ -80,6 +80,7 @@ menu:
- `PASSWD`: 数据库用户密码。
- `SSL_MODE`: PostgreSQL数据库是否启用SSL模式。
- `PATH`: Tidb 或者 SQLite3 数据文件存放路径。
- `LOG_SQL`: **true**: 显示生成的SQL默认为真。
## 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)
}
refName := git.RefEndName(opts.RefFullName)
if repo.IsBare && refName != repo.DefaultBranch {
repo.DefaultBranch = refName
}
// Change repository bare status and update last updated time.
repo.IsBare = repo.IsBare && opts.Commits.Len <= 0
if err = UpdateRepository(repo, false); err != nil {
@ -567,7 +572,6 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
return fmt.Errorf("Marshal: %v", err)
}
refName := git.RefEndName(opts.RefFullName)
if err = NotifyWatchers(&Action{
ActUserID: pusher.ID,
ActUser: pusher,

View File

@ -11,7 +11,6 @@ import (
"os"
"path"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
api "code.gitea.io/sdk/gitea"
@ -29,6 +28,7 @@ type Attachment struct {
CommentID int64
Name string
DownloadCount int64 `xorm:"DEFAULT 0"`
Size int64 `xorm:"DEFAULT 0"`
CreatedUnix util.TimeStamp `xorm:"created"`
}
@ -44,13 +44,12 @@ func (a *Attachment) IncreaseDownloadCount() error {
// APIFormat converts models.Attachment to api.Attachment
func (a *Attachment) APIFormat() *api.Attachment {
size, _ := a.Size()
return &api.Attachment{
ID: a.ID,
Name: a.Name,
Created: a.CreatedUnix.AsTime(),
DownloadCount: a.DownloadCount,
Size: size,
Size: a.Size,
UUID: a.UUID,
DownloadURL: a.DownloadURL(),
}
@ -67,25 +66,6 @@ func (a *Attachment) LocalPath() string {
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
func (a *Attachment) DownloadURL() string {
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)
}
// 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 {
return nil, err
}

View File

@ -23,15 +23,18 @@ const (
// ProtectedBranch struct
type ProtectedBranch struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"UNIQUE(s)"`
BranchName string `xorm:"UNIQUE(s)"`
CanPush bool `xorm:"NOT NULL DEFAULT false"`
EnableWhitelist bool
WhitelistUserIDs []int64 `xorm:"JSON TEXT"`
WhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
CreatedUnix util.TimeStamp `xorm:"created"`
UpdatedUnix util.TimeStamp `xorm:"updated"`
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"UNIQUE(s)"`
BranchName string `xorm:"UNIQUE(s)"`
CanPush bool `xorm:"NOT NULL DEFAULT false"`
EnableWhitelist bool
WhitelistUserIDs []int64 `xorm:"JSON TEXT"`
WhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
EnableMergeWhitelist bool `xorm:"NOT NULL DEFAULT false"`
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
@ -61,6 +64,28 @@ func (protectBranch *ProtectedBranch) CanUserPush(userID int64) bool {
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
func GetProtectedBranchByRepoID(RepoID int64) ([]*ProtectedBranch, error) {
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.
// This function also performs check if whitelist user and team's IDs have been changed
// 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 {
return fmt.Errorf("GetOwner: %v", err)
}
hasUsersChanged := !util.IsSliceInt64Eq(protectBranch.WhitelistUserIDs, whitelistUserIDs)
if hasUsersChanged {
protectBranch.WhitelistUserIDs = make([]int64, 0, len(whitelistUserIDs))
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)
}
whitelist, err := updateUserWhitelist(repo, protectBranch.WhitelistUserIDs, whitelistUserIDs)
if err != nil {
return err
}
protectBranch.WhitelistUserIDs = whitelist
// if the repo is in an orgniziation
hasTeamsChanged := !util.IsSliceInt64Eq(protectBranch.WhitelistTeamIDs, whitelistTeamIDs)
if hasTeamsChanged {
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)
}
}
whitelist, err = updateUserWhitelist(repo, protectBranch.MergeWhitelistUserIDs, mergeWhitelistUserIDs)
if err != nil {
return err
}
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
if protectBranch.ID == 0 {
@ -174,6 +194,73 @@ func (repo *Repository) IsProtectedBranch(branchName string, doer *User) (bool,
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.
func (repo *Repository) DeleteProtectedBranch(id int64) (err error) {
protectedBranch := &ProtectedBranch{

View File

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

View File

@ -171,6 +171,12 @@ var migrations = []Migration{
// v58 -> v59
NewMigration("add label descriptions", addLabelsDescriptions),
// 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),
}

View File

@ -6,95 +6,19 @@ package migrations
import (
"fmt"
"time"
"code.gitea.io/gitea/modules/setting"
"github.com/go-xorm/xorm"
)
func addIssueDependencies(x *xorm.Engine) (err error) {
type IssueDependency struct {
ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"NOT NULL"`
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"`
func addProtectedBranchMergeWhitelist(x *xorm.Engine) error {
type ProtectedBranch struct {
EnableMergeWhitelist bool `xorm:"NOT NULL DEFAULT false"`
MergeWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
MergeWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
}
if err = x.Sync(new(IssueDependency)); err != nil {
return fmt.Errorf("Error creating issue_dependency_table column definition: %v", err)
if err := x.Sync2(new(ProtectedBranch)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
// 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
return nil
}

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,
// so use log file to instead print to stdout.
x.SetLogger(log.XORMLogger)
x.ShowSQL(true)
x.ShowSQL(setting.LogSQL)
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)
} else if protected {
return ErrNotAllowedToMerge{

View File

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

View File

@ -114,6 +114,9 @@ type RepoSettingForm struct {
EnableTimetracker bool
AllowOnlyContributorsToTrackTime bool
EnableIssueDependencies bool
// Admin settings
EnableHealthCheck bool
}
// 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
type ProtectBranchForm struct {
Protected bool
EnableWhitelist bool
WhitelistUsers string
WhitelistTeams string
Protected bool
EnableWhitelist bool
WhitelistUsers string
WhitelistTeams string
EnableMergeWhitelist bool
MergeWhitelistUsers string
MergeWhitelistTeams string
}
// Validate validates the fields

View File

@ -159,6 +159,7 @@ var (
UseMSSQL bool
UsePostgreSQL bool
UseTiDB bool
LogSQL bool
// Indexer settings
Indexer struct {
@ -931,6 +932,7 @@ func NewContext() {
}
}
IterateBufferSize = Cfg.Section("database").Key("ITERATE_BUFFER_SIZE").MustInt(50)
LogSQL = Cfg.Section("database").Key("LOG_SQL").MustBool(true)
sec = Cfg.Section("attachment")
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.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.add_milestone_at=`fügte das Issue zum <b>%s</b> Meilenstein hinzu %s`
issues.change_milestone_at=`änderte den Meilenstein von <b>%s</b> zu <b>%s</b> %s`
issues.remove_milestone_at=`entfernte das Issue vom <b>%s</b> Meilenstein %s`
issues.add_milestone_at=`hat diesen Issue %[2]s zum <b>%[1]s</b> Meilenstein hinzugefügt`
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=`hat diesen Issue %[2]s vom <b>%[1]s</b> Meilenstein entfernt`
issues.deleted_milestone=`(gelöscht)`
issues.self_assign_at=`wies sich das Issue selbst zu %s`
issues.add_assignee_at=`wurde zugewiesen von <b>%s</b> %s`
issues.remove_assignee_at=`entfernte seine Zuweisung %s`
issues.self_assign_at=`hat sich das Issue %s selbst zugewiesen`
issues.add_assignee_at=`wurde %[1]s zugewiesen von <b>%[2]s</b>`
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.delete_branch_at=`löschte die Branch <b>%s</b> %s`
issues.open_tab=%d offen
@ -675,14 +675,14 @@ issues.action_milestone=Meilenstein
issues.action_milestone_no_select=Kein Meilenstein
issues.action_assignee=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.previous=Vorherige
issues.next=Nächste
issues.open_title=Offen
issues.closed_title=Geschlossen
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.no_content=Hier gibt es bis jetzt noch keinen Inhalt.
issues.close_issue=Schließen
@ -722,20 +722,20 @@ issues.subscribe=Abonnieren
issues.unsubscribe=Abbestellen
issues.tracker=Zeiterfassung
issues.start_tracking_short=Start
issues.start_tracking=Starte Zeiterfassungsstopuhr
issues.start_tracking_history=begann zu arbeiten %s
issues.start_tracking=Starte Zeiterfassung
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.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_short=Hinzufügen
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_minutes=Minuten
issues.add_time_sum_to_small=Es wurde keine Zeit eingetragen
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
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.protect_this_branch=Diese Branch schützen
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_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_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.add_protected_branch=Schutz aktivieren
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_rebase_merge = Allow rebase to merge commits
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.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
@ -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_teams = Teams whose members can push to this branch.
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.delete_protected_branch=Disable protection
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_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.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.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
@ -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_teams=Csoportok, melyeknek tagjai pusholhatnak az ágra.
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.delete_protected_branch=Védelem letiltása
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
organizations=Organisaties
search=Zoeken
code=Code
repo_no_results=Er zijn geen overeenkomende repositories gevonden.
user_no_results=Er zijn geen overeenkomende gebruikers gevonden.
org_no_results=Er zijn geen overeenkomende organisaties gevonden.
code_search_results=Zoekresultaten voor %s
[auth]
create_new_account=Account aanmaken
@ -610,8 +612,11 @@ issues.new.closed_milestone=Gesloten mijlpalen
issues.new.assignee=Toegewezen aan
issues.new.clear_assignee=Verwijder verantwoordelijke
issues.new.no_assignee=Geen verantwoordelijke
issues.no_ref=Geen Branch/Tag gespecificeerd
issues.create=Maak probleem
issues.new_label=Nieuw Label
issues.new_label_placeholder=Labelnaam…
issues.new_label_desc_placeholder=Omschrijving…
issues.create_label=Maak label
issues.label_templates.title=Laad een vooraf gedefinieerde set labels
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.deleted_milestone=` (verwijderd)`
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.close_tab=%d gesloten
issues.filter_label=Label
@ -671,6 +677,7 @@ issues.edit=Bewerken
issues.cancel=Annuleren
issues.save=Opslaan
issues.label_title=Labelnaam
issues.label_description=Label omschrijving
issues.label_color=Labelkleur
issues.label_count=%d labels
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.subscribe=Abonneren
issues.unsubscribe=Uitschrijven
issues.tracker=Tijd tracker
issues.start_tracking_short=Start
issues.start_tracking=Start tijdregistratie
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.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.rebase_merge_pull_request=Rebase en Merge
pulls.squash_merge_pull_request=Squash en Merge
milestones.new=Nieuwe mijlpaal
milestones.open_tab=%d geopend
@ -783,6 +793,7 @@ activity.period.halfweekly=3 dagen
activity.period.weekly=1 week
activity.period.monthly=1 maand
activity.overview=Overzicht
activity.active_prs_count_n=<strong>%d</strong> Actieve Pull Requests
activity.title.user_1=%d gebruiker
activity.title.user_n=%d gebruikers
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.merged_prs_label=Samengevoegd
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_n=Gesloten problemen
activity.title.issues_1=%d Probleem
@ -809,6 +821,7 @@ activity.published_release_label=Gepubliceerd
search=Zoek
search.search_repo=Zoek repository
search.results=Zoek resultaat voor "%s" in <a href="%s">%s</a>
settings=Instellingen
settings.options=Opties
@ -817,6 +830,7 @@ settings.collaboration.admin=Beheerder
settings.collaboration.write=Schrijf
settings.collaboration.read=Lees
settings.collaboration.undefined=Ongedefinieerd
settings.hooks=Webhooks
settings.githooks=Git-hooks
settings.basic_settings=Basis instellingen
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_issue_style.numeric=Nummeriek
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.admin_settings=Beheerdersinstellingen
settings.danger_zone=Gevaren zone
settings.new_owner_has_same_repo=De nieuwe eigenaar heeft al een repository met deze naam
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_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.confirm_wiki_delete=Wiki gegevens verwijderen
settings.wiki_deletion_success=De repository met wiki data is succesvol gewist.
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.
@ -866,6 +883,7 @@ settings.delete_collaborator=Verwijderen
settings.collaborator_deletion=Verwijder Medewerker
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.search_user_placeholder=Zoek gebruiker…
settings.org_not_allowed_to_be_collaborator=De organisatie kan niet toegevoegd worden als medewerker.
settings.user_is_org_member=Gebruiker is lid van de organisatie die als een medewerker kan niet worden toegevoegd.
settings.add_webhook=Webhook toevoegen
@ -901,6 +919,7 @@ settings.event_pull_request=Pull request
settings.event_push=Push
settings.event_push_desc=Git push naar een repository
settings.event_repository=Repository
settings.event_repository_desc=Repository gemaakt of verwijderd
settings.active=Actief
settings.add_hook_success=Nieuwe webhook toegevoegd.
settings.update_webhook=Bewerk webhook
@ -915,6 +934,7 @@ settings.slack_channel=Slack kanaal
settings.deploy_keys=Installeer sleutels
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.is_writable=Schrijftoegang toestaan
settings.no_deploy_keys=U hebt nog geen deploy sleutels toegevoegd.
settings.title=Titel
settings.deploy_key_content=Inhoud
@ -926,11 +946,15 @@ settings.deploy_key_deletion_success=Deploy sleutel werd met succes verwijderd!
settings.branches=Branches
settings.protected_branch=Branch bescherming
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_teams=Zoek teams
settings.add_protected_branch=Bescherming aanzetten
settings.delete_protected_branch=Bescherming uitzetten
settings.remove_protected_branch_success=%s is ontgrendeld
settings.choose_branch=Kies een branch…
settings.no_protected_branch=Er zijn geen beschermde branches
diff.browse_source=Bladeren bron
@ -959,6 +983,7 @@ release.title=Titel
release.content=Inhoud
release.write=Schrijf
release.preview=Voorbeeld
release.loading=Laden…
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.cancel=Annuleren
@ -983,6 +1008,7 @@ branch.deletion_success=%s is verwijderd.
branch.deletion_failed=%s verwijderen is mislukt.
branch.create_branch=Maak branch <strong>%s</strong>
branch.create_from=van '%s'
branch.create_success=Branch '%s' is met succes aangemaakt!
branch.deleted_by=Verwijderd door %s
[org]
@ -995,6 +1021,8 @@ people=Mensen
teams=Teams
lower_members=leden
lower_repositories=repositories
create_new_team=Nieuw team
create_team=Maak team
org_desc=Omschrijving
team_name=Teamnaam
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.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.search_repo_placeholder=Repository zoeken…
teams.add_team_repository=Nieuwe teamrepositorie aanmaken
teams.remove_repo=Verwijder
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
users=Gebruikers
organizations=Organisaties
repositories=Repositories
authentication=Authenticaties
config=Configuratie
notices=Systeem aankondigingen
@ -1115,6 +1145,7 @@ dashboard.total_gc_pause=Totaal GC verwerkingstijd
dashboard.last_gc_pause=Laatste GC verwerkingstijd
dashboard.gc_times=GC verwerkingen
users.user_manage_panel=Gebruikersbeheer paneel
users.new_account=Nieuw account aanmaken
users.name=Naam
users.activated=Geactiveerd
@ -1246,6 +1277,7 @@ config.mail_notify=E-mailnotificaties
config.disable_key_size_check=Controle op key-lengte uitschakelen
config.enable_captcha=CAPTCHA inschakelen
config.active_code_lives=Actieve Code leven
config.default_enable_timetracking=Time tracking standaard inschakelen
config.no_reply_address=No-reply emailadres
config.webhook_config=Webhook configuratie
@ -1261,6 +1293,7 @@ config.mailer_user=Gebruiker
config.mailer_use_sendmail=Gebruik Sendmail
config.mailer_sendmail_path=Sendmail pad
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.oauth_config=OAuth-configuratie
@ -1366,8 +1399,10 @@ no_unread=Je hebt geen ongelezen meldingen.
no_read=Je hebt geen gelezen meldingen.
mark_as_read=Markeer als gelezen
mark_as_unread=Markeer als ongelezen
mark_all_as_read=Markeer alles als gelezen
[gpg]
error.generate_hash=Genereren van commit hash mislukt
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

View File

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

View File

@ -1664,8 +1664,11 @@ function selectRange($list, $select, $from) {
}
$(function () {
if ($('.user.signin').length > 0) return;
$('form').areYouSure();
// Warn users that try to leave a page after entering data into a form.
// 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
$("#ssh-key-content").on('change paste keyup',function(){

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,13 +5,15 @@
package repo
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"
"net/http"
"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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -112,7 +112,7 @@ func Issues(ctx *context.Context) {
viewType := ctx.Query("type")
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) {
viewType = "all"
}

View File

@ -32,7 +32,7 @@ func TestInitializeLabels(t *testing.T) {
ctx := test.MockContext(t, "user2/repo1/labels/initialize")
test.LoadUser(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())
models.AssertExistsAndLoadBean(t, &models.Label{
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.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":
if !ctx.Repo.IsOwner() {
ctx.Error(404)

View File

@ -98,7 +98,7 @@ func SettingsProtectedBranch(c *context.Context) {
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
protectBranch, err := models.GetProtectedBranchBy(c.Repo.Repository.ID, branch)
@ -123,6 +123,7 @@ func SettingsProtectedBranch(c *context.Context) {
}
c.Data["Users"] = users
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() {
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["whitelist_teams"] = strings.Join(base.Int64sToStrings(protectBranch.WhitelistTeamIDs), ",")
c.Data["merge_whitelist_teams"] = strings.Join(base.Int64sToStrings(protectBranch.MergeWhitelistTeamIDs), ",")
}
c.Data["Branch"] = protectBranch
@ -166,7 +168,10 @@ func SettingsProtectedBranchPost(ctx *context.Context, f auth.ProtectBranchForm)
protectBranch.EnableWhitelist = f.EnableWhitelist
whitelistUsers, _ := base.StringsToInt64s(strings.Split(f.WhitelistUsers, ","))
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 {
ctx.ServerError("UpdateProtectBranch", err)
return

View File

@ -17,7 +17,7 @@
</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">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
<button class="ui blue button">{{.i18n.Tr "explore.search"}}</button>

View File

@ -187,7 +187,7 @@
{{end}}
<dt>{{.i18n.Tr "admin.config.mailer_user"}}</dt>
<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}}
<div class="inline field ui left">
<div class="ui input">

View File

@ -2,7 +2,7 @@
<div class="explore users">
{{template "explore/navbar" .}}
<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">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
<input type="hidden" name="tab" value="{{$.TabName}}">

View File

@ -15,7 +15,7 @@
</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">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
<input type="hidden" name="tab" value="{{$.TabName}}">

View File

@ -13,7 +13,7 @@
<div class="ui red message">
<p class="text left"><i class="octicon octicon-alert"></i> {{.i18n.Tr "org.settings.delete_prompt" | Str2html}}</p>
</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}}
<input class="fake" type="password">
<div class="inline required field {{if .Err_Password}}error{{end}}">

View File

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

View File

@ -10,7 +10,7 @@
</div>
{{if .RepoSearchEnabled}}
<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="ui action input">
<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">
<input type="hidden" name="type" value="{{$.ViewType}}"/>
<input type="hidden" name="state" value="{{$.State}}"/>

View File

@ -79,7 +79,7 @@
<li>
<a target="_blank" rel="noopener" href="{{AppSubUrl}}/attachments/{{.UUID}}">
<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>
</li>
{{end}}

View File

@ -3,7 +3,7 @@
{{template "repo/header" .}}
<div class="ui container">
<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">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "repo.search.search_repo"}}">
<button class="ui button" type="submit">

View File

@ -242,6 +242,29 @@
</form>
</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}}
<h4 class="ui top attached warning header">
{{.i18n.Tr "repo.settings.danger_zone"}}

View File

@ -60,6 +60,49 @@
</div>
{{end}}
</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 class="ui divider"></div>

View File

@ -2,7 +2,7 @@
<div class="user activate">
<div class="ui middle very relaxed page grid">
<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}}
<h2 class="ui top attached header">
{{.i18n.Tr "auth.active_your_account"}}

View File

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

View File

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

View File

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

View File

@ -10,7 +10,7 @@
<div class="ui red message">
<p class="text left"><i class="octicon octicon-alert"></i> {{.i18n.Tr "settings.delete_prompt" | Str2html}}</p>
</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}}
<input class="fake" type="password">
<div class="required field {{if .Err_Password}}error{{end}}">