Skip to content

Commit caccfb4

Browse files
committed
Move branch name validation to model
1 parent b4cca45 commit caccfb4

File tree

3 files changed

+102
-24
lines changed

3 files changed

+102
-24
lines changed

models/error.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,51 @@ func (err ErrBranchNotExist) Error() string {
649649
return fmt.Sprintf("branch does not exist [name: %s]", err.Name)
650650
}
651651

652+
// ErrBranchAlreadyExists represents an error that branch with such name already exists
653+
type ErrBranchAlreadyExists struct {
654+
BranchName string
655+
}
656+
657+
// IsErrBranchAlreadyExists checks if an error is an ErrBranchAlreadyExists.
658+
func IsErrBranchAlreadyExists(err error) bool {
659+
_, ok := err.(ErrBranchAlreadyExists)
660+
return ok
661+
}
662+
663+
func (err ErrBranchAlreadyExists) Error() string {
664+
return fmt.Sprintf("branch already exists [name: %s]", err.BranchName)
665+
}
666+
667+
// ErrBranchNameConflict represents an error that branch name conflicts with other branch
668+
type ErrBranchNameConflict struct {
669+
BranchName string
670+
}
671+
672+
// IsErrBranchNameConflict checks if an error is an ErrBranchNameConflict.
673+
func IsErrBranchNameConflict(err error) bool {
674+
_, ok := err.(ErrBranchNameConflict)
675+
return ok
676+
}
677+
678+
func (err ErrBranchNameConflict) Error() string {
679+
return fmt.Sprintf("branch conflicts with existing branch [name: %s]", err.BranchName)
680+
}
681+
682+
// ErrTagAlreadyExists represents an error that tag with such name already exists
683+
type ErrTagAlreadyExists struct {
684+
TagName string
685+
}
686+
687+
// IsErrTagAlreadyExists checks if an error is an ErrTagAlreadyExists.
688+
func IsErrTagAlreadyExists(err error) bool {
689+
_, ok := err.(ErrTagAlreadyExists)
690+
return ok
691+
}
692+
693+
func (err ErrTagAlreadyExists) Error() string {
694+
return fmt.Sprintf("tag already exists [name: %s]", err.TagName)
695+
}
696+
652697
// __ __ ___. .__ __
653698
// / \ / \ ____\_ |__ | |__ ____ ____ | | __
654699
// \ \/\/ // __ \| __ \| | \ / _ \ / _ \| |/ /

models/repo_branch.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,40 @@ func (repo *Repository) GetBranches() ([]*Branch, error) {
6363
return GetBranchesByPath(repo.RepoPath())
6464
}
6565

66+
// CheckBranchName validates branch name with existing repository branches
67+
func (repo *Repository) CheckBranchName(name string) error {
68+
gitRepo, err := git.OpenRepository(repo.RepoPath())
69+
if err != nil {
70+
return err
71+
}
72+
73+
if _, err := gitRepo.GetTag(name); err == nil {
74+
return ErrTagAlreadyExists{name}
75+
}
76+
77+
branches, err := repo.GetBranches()
78+
if err != nil {
79+
return err
80+
}
81+
82+
for _, branch := range branches {
83+
if branch.Name == name {
84+
return ErrBranchAlreadyExists{branch.Name}
85+
} else if (len(branch.Name) < len(name) && branch.Name+"/" == name[0:len(branch.Name)+1]) ||
86+
(len(branch.Name) > len(name) && name+"/" == branch.Name[0:len(name)+1]) {
87+
return ErrBranchNameConflict{branch.Name}
88+
}
89+
}
90+
return nil
91+
}
92+
6693
// CreateNewBranch creates a new repository branch
6794
func (repo *Repository) CreateNewBranch(doer *User, oldBranchName, branchName string) (err error) {
95+
// Check if branch name can be used
96+
if err := repo.CheckBranchName(branchName); err != nil {
97+
return err
98+
}
99+
68100
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
69101
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
70102

@@ -125,6 +157,11 @@ func (repo *Repository) updateLocalCopyToCommit(commit string) error {
125157

126158
// CreateNewBranchFromCommit creates a new repository branch
127159
func (repo *Repository) CreateNewBranchFromCommit(doer *User, commit, branchName string) (err error) {
160+
// Check if branch name can be used
161+
if err := repo.CheckBranchName(branchName); err != nil {
162+
return err
163+
}
164+
128165
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
129166
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
130167

routers/repo/branch.go

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package repo
66

77
import (
8+
"code.gitea.io/gitea/models"
89
"code.gitea.io/gitea/modules/auth"
910
"code.gitea.io/gitea/modules/base"
1011
"code.gitea.io/gitea/modules/context"
@@ -45,37 +46,32 @@ func CreateBranch(ctx *context.Context, form auth.NewBranchForm) {
4546
return
4647
}
4748

48-
branches, err := ctx.Repo.Repository.GetBranches()
49-
if err != nil {
50-
ctx.Handle(500, "GetBranches", err)
51-
return
49+
var err error
50+
if ctx.Repo.IsViewBranch {
51+
err = ctx.Repo.Repository.CreateNewBranch(ctx.User, ctx.Repo.BranchName, form.NewBranchName)
52+
} else {
53+
err = ctx.Repo.Repository.CreateNewBranchFromCommit(ctx.User, ctx.Repo.BranchName, form.NewBranchName)
5254
}
53-
54-
for _, branch := range branches {
55-
if branch.Name == form.NewBranchName {
56-
ctx.Flash.Error(ctx.Tr("repo.branch.branch_already_exists", branch.Name))
55+
if err != nil {
56+
if models.IsErrTagAlreadyExists(err) {
57+
e := err.(models.ErrTagAlreadyExists)
58+
ctx.Flash.Error(ctx.Tr("repo.branch.tag_collision", e.TagName))
5759
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchName)
5860
return
59-
} else if (len(branch.Name) < len(form.NewBranchName) && branch.Name+"/" == form.NewBranchName[0:len(branch.Name)+1]) ||
60-
(len(branch.Name) > len(form.NewBranchName) && form.NewBranchName+"/" == branch.Name[0:len(form.NewBranchName)+1]) {
61-
ctx.Flash.Error(ctx.Tr("repo.branch.branch_name_conflict", form.NewBranchName, branch.Name))
61+
}
62+
if models.IsErrBranchAlreadyExists(err) {
63+
e := err.(models.ErrBranchAlreadyExists)
64+
ctx.Flash.Error(ctx.Tr("repo.branch.branch_already_exists", e.BranchName))
65+
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchName)
66+
return
67+
}
68+
if models.IsErrBranchNameConflict(err) {
69+
e := err.(models.ErrBranchNameConflict)
70+
ctx.Flash.Error(ctx.Tr("repo.branch.branch_name_conflict", form.NewBranchName, e.BranchName))
6271
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchName)
6372
return
6473
}
65-
}
66-
67-
if _, err := ctx.Repo.GitRepo.GetTag(form.NewBranchName); err == nil {
68-
ctx.Flash.Error(ctx.Tr("repo.branch.tag_collision", form.NewBranchName))
69-
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchName)
70-
return
71-
}
7274

73-
if ctx.Repo.IsViewBranch {
74-
err = ctx.Repo.Repository.CreateNewBranch(ctx.User, ctx.Repo.BranchName, form.NewBranchName)
75-
} else {
76-
err = ctx.Repo.Repository.CreateNewBranchFromCommit(ctx.User, ctx.Repo.BranchName, form.NewBranchName)
77-
}
78-
if err != nil {
7975
ctx.Handle(500, "CreateNewBranch", err)
8076
return
8177
}

0 commit comments

Comments
 (0)