diff --git a/models/git/protected_branch.go b/models/git/protected_branch.go index 83f03898eb..e7747917a3 100644 --- a/models/git/protected_branch.go +++ b/models/git/protected_branch.go @@ -26,11 +26,11 @@ import ( // ProtectedBranch struct type ProtectedBranch struct { - ID int64 `xorm:"pk autoincr"` - RepoID int64 `xorm:"UNIQUE(s)"` - BranchName string `xorm:"UNIQUE(s)"` // a branch name or a glob match to branch name - globRule []glob.Glob `xorm:"-"` - CanPush bool `xorm:"NOT NULL DEFAULT false"` + ID int64 `xorm:"pk autoincr"` + RepoID int64 `xorm:"UNIQUE(s)"` + BranchName string `xorm:"UNIQUE(s)"` // a branch name or a glob match to branch name + globRule glob.Glob `xorm:"-"` + CanPush bool `xorm:"NOT NULL DEFAULT false"` EnableWhitelist bool WhitelistUserIDs []int64 `xorm:"JSON TEXT"` WhitelistTeamIDs []int64 `xorm:"JSON TEXT"` @@ -66,21 +66,10 @@ func (protectBranch *ProtectedBranch) Match(branchName string) bool { return true } if protectBranch.globRule == nil { - parts := strings.Split(protectBranch.BranchName, "/") - for _, part := range parts { - protectBranch.globRule = append(protectBranch.globRule, glob.MustCompile(part)) - } + protectBranch.globRule = glob.MustCompile(protectBranch.BranchName, '/') } - fields := strings.Split(branchName, "/") - if len(fields) != len(protectBranch.globRule) { - return false - } - for i := 0; i < len(fields); i++ { - if !protectBranch.globRule[i].Match(fields[i]) { - return false - } - } - return true + + return protectBranch.globRule.Match(branchName) } // CanUserPush returns if some user could push to this protected branch diff --git a/models/git/protected_branch_test.go b/models/git/protected_branch_test.go index 36005b7f4e..e1d1c211c4 100644 --- a/models/git/protected_branch_test.go +++ b/models/git/protected_branch_test.go @@ -18,10 +18,25 @@ func TestBranchRuleMatch(t *testing.T) { ExpectedMatch bool }{ { - Rule: "release/**", + Rule: "release/*", BranchName: "release/v1.17", ExpectedMatch: true, }, + { + Rule: "release/**/v1.17", + BranchName: "release/test/v1.17", + ExpectedMatch: true, + }, + { + Rule: "release/**/v1.17", + BranchName: "release/test/1/v1.17", + ExpectedMatch: true, + }, + { + Rule: "release/*/v1.17", + BranchName: "release/test/1/v1.17", + ExpectedMatch: false, + }, { Rule: "release/v*", BranchName: "release/v1.16", @@ -32,6 +47,11 @@ func TestBranchRuleMatch(t *testing.T) { BranchName: "release/v1.16", ExpectedMatch: false, }, + { + Rule: "**", + BranchName: "release/v1.16", + ExpectedMatch: true, + }, } for _, kase := range kases { diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 14d76775c4..56373c0a33 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2090,9 +2090,9 @@ settings.protect_unprotected_file_patterns = Unprotected file patterns (separate settings.protect_unprotected_file_patterns_desc = Unprotected files that are allowed to be changed directly if user has write access, bypassing push restriction. Multiple patterns can be separated using semicolon ('\;'). See github.com/gobwas/glob documentation for pattern syntax. Examples: .drone.yml, /docs/**/*.txt. settings.add_protected_branch = Enable protection settings.delete_protected_branch = Disable protection -settings.update_protect_branch_success = Branch protection for branch '%s' has been updated. -settings.remove_protected_branch_success = Branch protection for branch '%s' has been disabled. -settings.protected_branch_deletion = Disable Branch Protection +settings.update_protect_branch_success = Branch protection for rule '%s' has been updated. +settings.remove_protected_branch_success = Branch protection for rule '%s' has been removed. +settings.protected_branch_deletion = Delete Branch Protection settings.protected_branch_deletion_desc = Disabling branch protection allows users with write permission to push to the branch. Continue? settings.block_rejected_reviews = Block merge on rejected reviews settings.block_rejected_reviews_desc = Merging will not be possible when changes are requested by official reviewers, even if there are enough approvals. diff --git a/routers/web/repo/setting_protected_branch.go b/routers/web/repo/setting_protected_branch.go index 99707daa9c..6d299e9d24 100644 --- a/routers/web/repo/setting_protected_branch.go +++ b/routers/web/repo/setting_protected_branch.go @@ -291,7 +291,9 @@ func DeleteProtectedBranchRulePost(ctx *context.Context) { } ctx.Flash.Success(ctx.Tr("repo.settings.remove_protected_branch_success", rule.BranchName)) - ctx.Redirect(fmt.Sprintf("%s/settings/branches", ctx.Repo.RepoLink)) + ctx.JSON(http.StatusOK, map[string]interface{}{ + "redirect": fmt.Sprintf("%s/settings/branches", ctx.Repo.RepoLink), + }) } // RenameBranchPost responses for rename a branch diff --git a/routers/web/web.go b/routers/web/web.go index cf2cd72e75..ad554aa69c 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -809,7 +809,7 @@ func RegisterRoutes(m *web.Route) { m.Get("/", repo.ProtectedBranchRules) m.Combo("/new").Get(repo.SettingsProtectedBranch). Post(bindIgnErr(forms.ProtectBranchForm{}), context.RepoMustNotBeArchived(), repo.SettingsProtectedBranchPost) - m.Get("/{id}/delete", repo.DeleteProtectedBranchRulePost) + m.Post("/{id}/delete", repo.DeleteProtectedBranchRulePost) m.Combo("/{id}").Get(repo.SettingsProtectedBranch). Post(bindIgnErr(forms.ProtectBranchForm{}), context.RepoMustNotBeArchived(), repo.SettingsProtectedBranchPost) }, repo.MustBeNotEmpty) diff --git a/templates/repo/settings/branches.tmpl b/templates/repo/settings/branches.tmpl index c4469109f1..181bb976dc 100644 --- a/templates/repo/settings/branches.tmpl +++ b/templates/repo/settings/branches.tmpl @@ -47,7 +47,7 @@
- @@ -61,7 +61,8 @@
{{.BranchName}}
{{$.locale.Tr "repo.settings.edit_protected_branch"}} - {{$.locale.Tr "repo.settings.protected_branch.delete_rule"}} + {{else}} @@ -97,4 +98,16 @@ {{end}}
+ + + {{template "base/footer" .}}