@@ -166,10 +166,36 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
166166 }
167167
168168 var err error
169- protectBranch , err = git_model .GetProtectedBranchRuleByName (ctx , ctx .Repo .Repository .ID , f .RuleName )
170- if err != nil {
171- ctx .ServerError ("GetProtectBranchOfRepoByName" , err )
172- return
169+ if f .RuleID > 0 {
170+ // If the RuleID isn't 0, it must be an edit operation. So we get rule by id.
171+ protectBranch , err = git_model .GetProtectedBranchRuleByID (ctx , ctx .Repo .Repository .ID , f .RuleID )
172+ if err != nil {
173+ ctx .ServerError ("GetProtectBranchOfRepoByID" , err )
174+ return
175+ }
176+ if protectBranch != nil && protectBranch .RuleName != f .RuleName {
177+ // RuleName changed. We need to check if there is a rule with the same name.
178+ // If a rule with the same name exists, an error should be returned.
179+ sameNameProtectBranch , err := git_model .GetProtectedBranchRuleByName (ctx , ctx .Repo .Repository .ID , f .RuleName )
180+ if err != nil {
181+ ctx .ServerError ("GetProtectBranchOfRepoByName" , err )
182+ return
183+ }
184+ if sameNameProtectBranch != nil {
185+ ctx .Flash .Error (ctx .Tr ("repo.settings.protected_branch_duplicate_rule_name" ))
186+ ctx .Redirect (fmt .Sprintf ("%s/settings/branches/edit?rule_name=%s" , ctx .Repo .RepoLink , protectBranch .RuleName ))
187+ return
188+ }
189+ }
190+ } else {
191+ // FIXME: If a new ProtectBranch has a duplicate RuleName, an error should be returned.
192+ // Currently, if a new ProtectBranch with a duplicate RuleName is created, the existing ProtectBranch will be updated.
193+ // But we cannot modify this logic now because many unit tests rely on it.
194+ protectBranch , err = git_model .GetProtectedBranchRuleByName (ctx , ctx .Repo .Repository .ID , f .RuleName )
195+ if err != nil {
196+ ctx .ServerError ("GetProtectBranchOfRepoByName" , err )
197+ return
198+ }
173199 }
174200 if protectBranch == nil {
175201 // No options found, create defaults.
0 commit comments