diff options
author | 6543 <6543@obermui.de> | 2021-02-03 20:06:13 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-03 20:06:13 +0100 |
commit | 0d1444751f755c624ffb4c56cb0020ce7a083c77 (patch) | |
tree | c00ab7d4a1b120f4fb4a70db134e5d712bef91ed /modules/git | |
parent | c295a27d4a8ef9a3a75280306e1ed94daa3b001d (diff) | |
download | gitea-0d1444751f755c624ffb4c56cb0020ce7a083c77.tar.gz gitea-0d1444751f755c624ffb4c56cb0020ce7a083c77.zip |
[API] Add pagination to ListBranches (#14524)
* make PaginateUserSlice generic -> PaginateSlice
* Add pagination to ListBranches
* add skip, limit to Repository.GetBranches()
* Move routers/api/v1/utils/utils PaginateSlice -> modules/util/paginate.go
* repo_module.GetBranches paginate
* fix & rename & more logging
* better description
Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: a1012112796 <1012112796@qq.com>
Diffstat (limited to 'modules/git')
-rw-r--r-- | modules/git/repo_branch.go | 11 | ||||
-rw-r--r-- | modules/git/repo_branch_gogit.go | 19 | ||||
-rw-r--r-- | modules/git/repo_branch_nogogit.go | 50 | ||||
-rw-r--r-- | modules/git/repo_branch_test.go | 19 | ||||
-rw-r--r-- | modules/git/repo_tag_nogogit.go | 5 |
5 files changed, 80 insertions, 24 deletions
diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go index 25438530f5..58781eb1c7 100644 --- a/modules/git/repo_branch.go +++ b/modules/git/repo_branch.go @@ -78,16 +78,17 @@ func (repo *Repository) GetBranch(branch string) (*Branch, error) { } // GetBranchesByPath returns a branch by it's path -func GetBranchesByPath(path string) ([]*Branch, error) { +// if limit = 0 it will not limit +func GetBranchesByPath(path string, skip, limit int) ([]*Branch, int, error) { gitRepo, err := OpenRepository(path) if err != nil { - return nil, err + return nil, 0, err } defer gitRepo.Close() - brs, err := gitRepo.GetBranches() + brs, countAll, err := gitRepo.GetBranches(skip, limit) if err != nil { - return nil, err + return nil, 0, err } branches := make([]*Branch, len(brs)) @@ -99,7 +100,7 @@ func GetBranchesByPath(path string) ([]*Branch, error) { } } - return branches, nil + return branches, countAll, nil } // DeleteBranchOptions Option(s) for delete branch diff --git a/modules/git/repo_branch_gogit.go b/modules/git/repo_branch_gogit.go index 65cb77a8b5..b00253f6ff 100644 --- a/modules/git/repo_branch_gogit.go +++ b/modules/git/repo_branch_gogit.go @@ -25,21 +25,32 @@ func (repo *Repository) IsBranchExist(name string) bool { return reference.Type() != plumbing.InvalidReference } -// GetBranches returns all branches of the repository. -func (repo *Repository) GetBranches() ([]string, error) { +// GetBranches returns branches from the repository, skipping skip initial branches and +// returning at most limit branches, or all branches if limit is 0. +func (repo *Repository) GetBranches(skip, limit int) ([]string, int, error) { var branchNames []string branches, err := repo.gogitRepo.Branches() if err != nil { - return nil, err + return nil, 0, err } + i := 0 + count := 0 _ = branches.ForEach(func(branch *plumbing.Reference) error { + count++ + if i < skip { + i++ + return nil + } else if limit != 0 && count > skip+limit { + return nil + } + branchNames = append(branchNames, strings.TrimPrefix(branch.Name().String(), BranchPrefix)) return nil }) // TODO: Sort? - return branchNames, nil + return branchNames, count, nil } diff --git a/modules/git/repo_branch_nogogit.go b/modules/git/repo_branch_nogogit.go index 5ec46d725e..0628a57285 100644 --- a/modules/git/repo_branch_nogogit.go +++ b/modules/git/repo_branch_nogogit.go @@ -21,14 +21,14 @@ func (repo *Repository) IsBranchExist(name string) bool { return IsReferenceExist(repo.Path, BranchPrefix+name) } -// GetBranches returns all branches of the repository. -func (repo *Repository) GetBranches() ([]string, error) { - return callShowRef(repo.Path, BranchPrefix, "--heads") +// GetBranches returns branches from the repository, skipping skip initial branches and +// returning at most limit branches, or all branches if limit is 0. +func (repo *Repository) GetBranches(skip, limit int) ([]string, int, error) { + return callShowRef(repo.Path, BranchPrefix, "--heads", skip, limit) } -func callShowRef(repoPath, prefix, arg string) ([]string, error) { - var branchNames []string - +// callShowRef return refs, if limit = 0 it will not limit +func callShowRef(repoPath, prefix, arg string, skip, limit int) (branchNames []string, countAll int, err error) { stdoutReader, stdoutWriter := io.Pipe() defer func() { _ = stdoutReader.Close() @@ -49,8 +49,21 @@ func callShowRef(repoPath, prefix, arg string) ([]string, error) { } }() + i := 0 bufReader := bufio.NewReader(stdoutReader) - for { + for i < skip { + _, isPrefix, err := bufReader.ReadLine() + if err == io.EOF { + return branchNames, i, nil + } + if err != nil { + return nil, 0, err + } + if !isPrefix { + i++ + } + } + for limit == 0 || i < skip+limit { // The output of show-ref is simply a list: // <sha> SP <ref> LF _, err := bufReader.ReadSlice(' ') @@ -59,24 +72,39 @@ func callShowRef(repoPath, prefix, arg string) ([]string, error) { _, err = bufReader.ReadSlice(' ') } if err == io.EOF { - return branchNames, nil + return branchNames, i, nil } if err != nil { - return nil, err + return nil, 0, err } branchName, err := bufReader.ReadString('\n') if err == io.EOF { // This shouldn't happen... but we'll tolerate it for the sake of peace - return branchNames, nil + return branchNames, i, nil } if err != nil { - return nil, err + return nil, i, err } branchName = strings.TrimPrefix(branchName, prefix) if len(branchName) > 0 { branchName = branchName[:len(branchName)-1] } branchNames = append(branchNames, branchName) + i++ + } + // count all refs + for limit != 0 { + _, isPrefix, err := bufReader.ReadLine() + if err == io.EOF { + return branchNames, i, nil + } + if err != nil { + return nil, 0, err + } + if !isPrefix { + i++ + } } + return branchNames, i, nil } diff --git a/modules/git/repo_branch_test.go b/modules/git/repo_branch_test.go index 33d31aef68..05d5237e6a 100644 --- a/modules/git/repo_branch_test.go +++ b/modules/git/repo_branch_test.go @@ -17,11 +17,26 @@ func TestRepository_GetBranches(t *testing.T) { assert.NoError(t, err) defer bareRepo1.Close() - branches, err := bareRepo1.GetBranches() + branches, countAll, err := bareRepo1.GetBranches(0, 2) + + assert.NoError(t, err) + assert.Len(t, branches, 2) + assert.EqualValues(t, 3, countAll) + assert.ElementsMatch(t, []string{"branch1", "branch2"}, branches) + + branches, countAll, err = bareRepo1.GetBranches(0, 0) assert.NoError(t, err) assert.Len(t, branches, 3) + assert.EqualValues(t, 3, countAll) assert.ElementsMatch(t, []string{"branch1", "branch2", "master"}, branches) + + branches, countAll, err = bareRepo1.GetBranches(5, 1) + + assert.NoError(t, err) + assert.Len(t, branches, 0) + assert.EqualValues(t, 3, countAll) + assert.ElementsMatch(t, []string{}, branches) } func BenchmarkRepository_GetBranches(b *testing.B) { @@ -33,7 +48,7 @@ func BenchmarkRepository_GetBranches(b *testing.B) { defer bareRepo1.Close() for i := 0; i < b.N; i++ { - _, err := bareRepo1.GetBranches() + _, _, err := bareRepo1.GetBranches(0, 0) if err != nil { b.Fatal(err) } diff --git a/modules/git/repo_tag_nogogit.go b/modules/git/repo_tag_nogogit.go index 83cbc58e34..b3fa5d6dc4 100644 --- a/modules/git/repo_tag_nogogit.go +++ b/modules/git/repo_tag_nogogit.go @@ -13,6 +13,7 @@ func (repo *Repository) IsTagExist(name string) bool { } // GetTags returns all tags of the repository. -func (repo *Repository) GetTags() ([]string, error) { - return callShowRef(repo.Path, TagPrefix, "--tags") +func (repo *Repository) GetTags() (tags []string, err error) { + tags, _, err = callShowRef(repo.Path, TagPrefix, "--tags", 0, 0) + return } |