Skip to content

Commit f3e09cc

Browse files
authored
Merge branch 'main' into codebase-fake-input
2 parents 95a8ac8 + 9e6e1dc commit f3e09cc

File tree

10 files changed

+106
-58
lines changed

10 files changed

+106
-58
lines changed

modules/context/repo.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
584584
}
585585
ctx.Data["Tags"] = tags
586586

587-
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
587+
brs, _, err := ctx.Repo.GitRepo.GetBranchNames(0, 0)
588588
if err != nil {
589589
ctx.ServerError("GetBranches", err)
590590
return
@@ -810,7 +810,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
810810
if len(ctx.Params("*")) == 0 {
811811
refName = ctx.Repo.Repository.DefaultBranch
812812
if !ctx.Repo.GitRepo.IsBranchExist(refName) {
813-
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
813+
brs, _, err := ctx.Repo.GitRepo.GetBranchNames(0, 0)
814814
if err != nil {
815815
ctx.ServerError("GetBranches", err)
816816
return

modules/git/repo_branch.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,17 +95,22 @@ func GetBranchesByPath(path string, skip, limit int) ([]*Branch, int, error) {
9595
}
9696
defer gitRepo.Close()
9797

98-
brs, countAll, err := gitRepo.GetBranches(skip, limit)
98+
return gitRepo.GetBranches(skip, limit)
99+
}
100+
101+
// GetBranches returns a slice of *git.Branch
102+
func (repo *Repository) GetBranches(skip, limit int) ([]*Branch, int, error) {
103+
brs, countAll, err := repo.GetBranchNames(skip, limit)
99104
if err != nil {
100105
return nil, 0, err
101106
}
102107

103108
branches := make([]*Branch, len(brs))
104109
for i := range brs {
105110
branches[i] = &Branch{
106-
Path: path,
111+
Path: repo.Path,
107112
Name: brs[i],
108-
gitRepo: gitRepo,
113+
gitRepo: repo,
109114
}
110115
}
111116

modules/git/repo_branch_gogit.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
package git
1010

1111
import (
12+
"context"
1213
"strings"
1314

1415
"github.com/go-git/go-git/v5/plumbing"
@@ -52,7 +53,7 @@ func (repo *Repository) IsBranchExist(name string) bool {
5253

5354
// GetBranches returns branches from the repository, skipping skip initial branches and
5455
// returning at most limit branches, or all branches if limit is 0.
55-
func (repo *Repository) GetBranches(skip, limit int) ([]string, int, error) {
56+
func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) {
5657
var branchNames []string
5758

5859
branches, err := repo.gogitRepo.Branches()
@@ -79,3 +80,26 @@ func (repo *Repository) GetBranches(skip, limit int) ([]string, int, error) {
7980

8081
return branchNames, count, nil
8182
}
83+
84+
// WalkReferences walks all the references from the repository
85+
func WalkReferences(ctx context.Context, repoPath string, walkfn func(string) error) (int, error) {
86+
repo, err := OpenRepositoryCtx(ctx, repoPath)
87+
if err != nil {
88+
return 0, err
89+
}
90+
defer repo.Close()
91+
92+
i := 0
93+
iter, err := repo.gogitRepo.References()
94+
if err != nil {
95+
return i, err
96+
}
97+
defer iter.Close()
98+
99+
err = iter.ForEach(func(ref *plumbing.Reference) error {
100+
err := walkfn(string(ref.Name()))
101+
i++
102+
return err
103+
})
104+
return i, err
105+
}

modules/git/repo_branch_nogogit.go

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,29 @@ func (repo *Repository) IsBranchExist(name string) bool {
6161
return repo.IsReferenceExist(BranchPrefix + name)
6262
}
6363

64-
// GetBranches returns branches from the repository, skipping skip initial branches and
64+
// GetBranchNames returns branches from the repository, skipping skip initial branches and
6565
// returning at most limit branches, or all branches if limit is 0.
66-
func (repo *Repository) GetBranches(skip, limit int) ([]string, int, error) {
66+
func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) {
6767
return callShowRef(repo.Ctx, repo.Path, BranchPrefix, "--heads", skip, limit)
6868
}
6969

70+
// WalkReferences walks all the references from the repository
71+
func WalkReferences(ctx context.Context, repoPath string, walkfn func(string) error) (int, error) {
72+
return walkShowRef(ctx, repoPath, "", 0, 0, walkfn)
73+
}
74+
7075
// callShowRef return refs, if limit = 0 it will not limit
7176
func callShowRef(ctx context.Context, repoPath, prefix, arg string, skip, limit int) (branchNames []string, countAll int, err error) {
77+
countAll, err = walkShowRef(ctx, repoPath, arg, skip, limit, func(branchName string) error {
78+
branchName = strings.TrimPrefix(branchName, prefix)
79+
branchNames = append(branchNames, branchName)
80+
81+
return nil
82+
})
83+
return
84+
}
85+
86+
func walkShowRef(ctx context.Context, repoPath, arg string, skip, limit int, walkfn func(string) error) (countAll int, err error) {
7287
stdoutReader, stdoutWriter := io.Pipe()
7388
defer func() {
7489
_ = stdoutReader.Close()
@@ -77,7 +92,11 @@ func callShowRef(ctx context.Context, repoPath, prefix, arg string, skip, limit
7792

7893
go func() {
7994
stderrBuilder := &strings.Builder{}
80-
err := NewCommandContext(ctx, "show-ref", arg).RunInDirPipeline(repoPath, stdoutWriter, stderrBuilder)
95+
args := []string{"show-ref"}
96+
if arg != "" {
97+
args = append(args, arg)
98+
}
99+
err := NewCommandContext(ctx, args...).RunInDirPipeline(repoPath, stdoutWriter, stderrBuilder)
81100
if err != nil {
82101
if stderrBuilder.Len() == 0 {
83102
_ = stdoutWriter.Close()
@@ -94,10 +113,10 @@ func callShowRef(ctx context.Context, repoPath, prefix, arg string, skip, limit
94113
for i < skip {
95114
_, isPrefix, err := bufReader.ReadLine()
96115
if err == io.EOF {
97-
return branchNames, i, nil
116+
return i, nil
98117
}
99118
if err != nil {
100-
return nil, 0, err
119+
return 0, err
101120
}
102121
if !isPrefix {
103122
i++
@@ -112,39 +131,42 @@ func callShowRef(ctx context.Context, repoPath, prefix, arg string, skip, limit
112131
_, err = bufReader.ReadSlice(' ')
113132
}
114133
if err == io.EOF {
115-
return branchNames, i, nil
134+
return i, nil
116135
}
117136
if err != nil {
118-
return nil, 0, err
137+
return 0, err
119138
}
120139

121140
branchName, err := bufReader.ReadString('\n')
122141
if err == io.EOF {
123142
// This shouldn't happen... but we'll tolerate it for the sake of peace
124-
return branchNames, i, nil
143+
return i, nil
125144
}
126145
if err != nil {
127-
return nil, i, err
146+
return i, err
128147
}
129-
branchName = strings.TrimPrefix(branchName, prefix)
148+
130149
if len(branchName) > 0 {
131150
branchName = branchName[:len(branchName)-1]
132151
}
133-
branchNames = append(branchNames, branchName)
152+
err = walkfn(branchName)
153+
if err != nil {
154+
return i, err
155+
}
134156
i++
135157
}
136158
// count all refs
137159
for limit != 0 {
138160
_, isPrefix, err := bufReader.ReadLine()
139161
if err == io.EOF {
140-
return branchNames, i, nil
162+
return i, nil
141163
}
142164
if err != nil {
143-
return nil, 0, err
165+
return 0, err
144166
}
145167
if !isPrefix {
146168
i++
147169
}
148170
}
149-
return branchNames, i, nil
171+
return i, nil
150172
}

modules/git/repo_branch_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,21 @@ func TestRepository_GetBranches(t *testing.T) {
1717
assert.NoError(t, err)
1818
defer bareRepo1.Close()
1919

20-
branches, countAll, err := bareRepo1.GetBranches(0, 2)
20+
branches, countAll, err := bareRepo1.GetBranchNames(0, 2)
2121

2222
assert.NoError(t, err)
2323
assert.Len(t, branches, 2)
2424
assert.EqualValues(t, 3, countAll)
2525
assert.ElementsMatch(t, []string{"branch1", "branch2"}, branches)
2626

27-
branches, countAll, err = bareRepo1.GetBranches(0, 0)
27+
branches, countAll, err = bareRepo1.GetBranchNames(0, 0)
2828

2929
assert.NoError(t, err)
3030
assert.Len(t, branches, 3)
3131
assert.EqualValues(t, 3, countAll)
3232
assert.ElementsMatch(t, []string{"branch1", "branch2", "master"}, branches)
3333

34-
branches, countAll, err = bareRepo1.GetBranches(5, 1)
34+
branches, countAll, err = bareRepo1.GetBranchNames(5, 1)
3535

3636
assert.NoError(t, err)
3737
assert.Len(t, branches, 0)
@@ -48,7 +48,7 @@ func BenchmarkRepository_GetBranches(b *testing.B) {
4848
defer bareRepo1.Close()
4949

5050
for i := 0; i < b.N; i++ {
51-
_, _, err := bareRepo1.GetBranches(0, 0)
51+
_, _, err := bareRepo1.GetBranchNames(0, 0)
5252
if err != nil {
5353
b.Fatal(err)
5454
}

routers/web/repo/branch.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,14 @@ func redirect(ctx *context.Context) {
165165
// loadBranches loads branches from the repository limited by page & pageSize.
166166
// NOTE: May write to context on error.
167167
func loadBranches(ctx *context.Context, skip, limit int) ([]*Branch, int) {
168-
defaultBranch, err := repo_service.GetBranch(ctx.Repo.Repository, ctx.Repo.Repository.DefaultBranch)
168+
defaultBranch, err := ctx.Repo.GitRepo.GetBranch(ctx.Repo.Repository.DefaultBranch)
169169
if err != nil {
170170
log.Error("loadBranches: get default branch: %v", err)
171171
ctx.ServerError("GetDefaultBranch", err)
172172
return nil, 0
173173
}
174174

175-
rawBranches, totalNumOfBranches, err := repo_service.GetBranches(ctx.Repo.Repository, skip, limit)
175+
rawBranches, totalNumOfBranches, err := ctx.Repo.GitRepo.GetBranches(skip, limit)
176176
if err != nil {
177177
log.Error("GetBranches: %v", err)
178178
ctx.ServerError("GetBranches", err)

routers/web/repo/compare.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ func getBranchesAndTagsForRepo(repo *models.Repository) (branches, tags []string
660660
}
661661
defer gitRepo.Close()
662662

663-
branches, _, err = gitRepo.GetBranches(0, 0)
663+
branches, _, err = gitRepo.GetBranchNames(0, 0)
664664
if err != nil {
665665
return nil, nil, err
666666
}
@@ -711,7 +711,7 @@ func CompareDiff(ctx *context.Context) {
711711
return
712712
}
713713

714-
headBranches, _, err := ci.HeadGitRepo.GetBranches(0, 0)
714+
headBranches, _, err := ci.HeadGitRepo.GetBranchNames(0, 0)
715715
if err != nil {
716716
ctx.ServerError("GetBranches", err)
717717
return

routers/web/repo/issue.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ func RetrieveRepoMetas(ctx *context.Context, repo *models.Repository, isPull boo
690690
return nil
691691
}
692692

693-
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
693+
brs, _, err := ctx.Repo.GitRepo.GetBranchNames(0, 0)
694694
if err != nil {
695695
ctx.ServerError("GetBranches", err)
696696
return nil

services/repository/adopt.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ func adoptRepository(ctx context.Context, repoPath string, u *user_model.User, r
142142

143143
repo.DefaultBranch = strings.TrimPrefix(repo.DefaultBranch, git.BranchPrefix)
144144
}
145-
branches, _, _ := gitRepo.GetBranches(0, 0)
145+
branches, _, _ := gitRepo.GetBranchNames(0, 0)
146146
found := false
147147
hasDefault := false
148148
hasMaster := false

services/repository/branch.go

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
package repository
66

77
import (
8+
"context"
89
"errors"
910
"fmt"
11+
"strings"
1012

1113
"code.gitea.io/gitea/models"
1214
user_model "code.gitea.io/gitea/models/user"
@@ -20,7 +22,7 @@ import (
2022
// CreateNewBranch creates a new repository branch
2123
func CreateNewBranch(doer *user_model.User, repo *models.Repository, oldBranchName, branchName string) (err error) {
2224
// Check if branch name can be used
23-
if err := checkBranchName(repo, branchName); err != nil {
25+
if err := checkBranchName(git.DefaultContext, repo, branchName); err != nil {
2426
return err
2527
}
2628

@@ -65,44 +67,39 @@ func GetBranches(repo *models.Repository, skip, limit int) ([]*git.Branch, int,
6567
}
6668

6769
// checkBranchName validates branch name with existing repository branches
68-
func checkBranchName(repo *models.Repository, name string) error {
69-
gitRepo, err := git.OpenRepository(repo.RepoPath())
70-
if err != nil {
71-
return err
72-
}
73-
defer gitRepo.Close()
74-
75-
branches, _, err := GetBranches(repo, 0, 0)
76-
if err != nil {
77-
return err
78-
}
79-
80-
for _, branch := range branches {
81-
if branch.Name == name {
70+
func checkBranchName(ctx context.Context, repo *models.Repository, name string) error {
71+
_, err := git.WalkReferences(ctx, repo.RepoPath(), func(refName string) error {
72+
branchRefName := strings.TrimPrefix(refName, git.BranchPrefix)
73+
switch {
74+
case branchRefName == name:
8275
return models.ErrBranchAlreadyExists{
83-
BranchName: branch.Name,
76+
BranchName: name,
8477
}
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]) {
78+
// If branchRefName like a/b but we want to create a branch named a then we have a conflict
79+
case strings.HasPrefix(branchRefName, name+"/"):
8780
return models.ErrBranchNameConflict{
88-
BranchName: branch.Name,
81+
BranchName: branchRefName,
82+
}
83+
// Conversely if branchRefName like a but we want to create a branch named a/b then we also have a conflict
84+
case strings.HasPrefix(name, branchRefName+"/"):
85+
return models.ErrBranchNameConflict{
86+
BranchName: branchRefName,
87+
}
88+
case refName == git.TagPrefix+name:
89+
return models.ErrTagAlreadyExists{
90+
TagName: name,
8991
}
9092
}
91-
}
92-
93-
if _, err := gitRepo.GetTag(name); err == nil {
94-
return models.ErrTagAlreadyExists{
95-
TagName: name,
96-
}
97-
}
93+
return nil
94+
})
9895

99-
return nil
96+
return err
10097
}
10198

10299
// CreateNewBranchFromCommit creates a new repository branch
103100
func CreateNewBranchFromCommit(doer *user_model.User, repo *models.Repository, commit, branchName string) (err error) {
104101
// Check if branch name can be used
105-
if err := checkBranchName(repo, branchName); err != nil {
102+
if err := checkBranchName(git.DefaultContext, repo, branchName); err != nil {
106103
return err
107104
}
108105

0 commit comments

Comments
 (0)