2020-12-17 17:00:47 +03:00
// Copyright 2015 The Gogs Authors. All rights reserved.
// Copyright 2018 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2021-08-24 19:47:09 +03:00
//go:build !gogit
2020-12-17 17:00:47 +03:00
// +build !gogit
package git
import (
"bufio"
2021-06-21 01:39:12 +03:00
"bytes"
2020-12-17 17:00:47 +03:00
"io"
"strings"
2021-06-25 19:54:08 +03:00
"code.gitea.io/gitea/modules/log"
2020-12-17 17:00:47 +03:00
)
2021-06-21 01:39:12 +03:00
// IsObjectExist returns true if given reference exists in the repository.
func ( repo * Repository ) IsObjectExist ( name string ) bool {
if name == "" {
return false
}
wr , rd , cancel := repo . CatFileBatchCheck ( )
defer cancel ( )
_ , err := wr . Write ( [ ] byte ( name + "\n" ) )
if err != nil {
2021-06-25 19:54:08 +03:00
log . Debug ( "Error writing to CatFileBatchCheck %v" , err )
2021-06-21 01:39:12 +03:00
return false
}
sha , _ , _ , err := ReadBatchLine ( rd )
return err == nil && bytes . HasPrefix ( sha , [ ] byte ( strings . TrimSpace ( name ) ) )
}
2021-05-10 04:27:03 +03:00
// IsReferenceExist returns true if given reference exists in the repository.
func ( repo * Repository ) IsReferenceExist ( name string ) bool {
if name == "" {
return false
}
wr , rd , cancel := repo . CatFileBatchCheck ( )
defer cancel ( )
_ , err := wr . Write ( [ ] byte ( name + "\n" ) )
if err != nil {
2021-06-25 19:54:08 +03:00
log . Debug ( "Error writing to CatFileBatchCheck %v" , err )
2021-05-10 04:27:03 +03:00
return false
}
_ , _ , _ , err = ReadBatchLine ( rd )
return err == nil
}
2020-12-17 17:00:47 +03:00
// IsBranchExist returns true if given branch exists in current repository.
func ( repo * Repository ) IsBranchExist ( name string ) bool {
if name == "" {
return false
}
2021-05-10 04:27:03 +03:00
return repo . IsReferenceExist ( BranchPrefix + name )
2020-12-17 17:00:47 +03:00
}
2021-02-03 22:06:13 +03:00
// 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 )
2020-12-17 17:00:47 +03:00
}
2021-02-03 22:06:13 +03:00
// 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 ) {
2020-12-17 17:00:47 +03:00
stdoutReader , stdoutWriter := io . Pipe ( )
defer func ( ) {
_ = stdoutReader . Close ( )
_ = stdoutWriter . Close ( )
} ( )
go func ( ) {
stderrBuilder := & strings . Builder { }
err := NewCommand ( "show-ref" , arg ) . RunInDirPipeline ( repoPath , stdoutWriter , stderrBuilder )
if err != nil {
if stderrBuilder . Len ( ) == 0 {
_ = stdoutWriter . Close ( )
return
}
_ = stdoutWriter . CloseWithError ( ConcatenateError ( err , stderrBuilder . String ( ) ) )
} else {
_ = stdoutWriter . Close ( )
}
} ( )
2021-02-03 22:06:13 +03:00
i := 0
2020-12-17 17:00:47 +03:00
bufReader := bufio . NewReader ( stdoutReader )
2021-02-03 22:06:13 +03:00
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 {
2020-12-17 17:00:47 +03:00
// The output of show-ref is simply a list:
// <sha> SP <ref> LF
_ , err := bufReader . ReadSlice ( ' ' )
for err == bufio . ErrBufferFull {
// This shouldn't happen but we'll tolerate it for the sake of peace
_ , err = bufReader . ReadSlice ( ' ' )
}
if err == io . EOF {
2021-02-03 22:06:13 +03:00
return branchNames , i , nil
2020-12-17 17:00:47 +03:00
}
if err != nil {
2021-02-03 22:06:13 +03:00
return nil , 0 , err
2020-12-17 17:00:47 +03:00
}
branchName , err := bufReader . ReadString ( '\n' )
if err == io . EOF {
// This shouldn't happen... but we'll tolerate it for the sake of peace
2021-02-03 22:06:13 +03:00
return branchNames , i , nil
2020-12-17 17:00:47 +03:00
}
if err != nil {
2021-02-03 22:06:13 +03:00
return nil , i , err
2020-12-17 17:00:47 +03:00
}
branchName = strings . TrimPrefix ( branchName , prefix )
if len ( branchName ) > 0 {
branchName = branchName [ : len ( branchName ) - 1 ]
}
branchNames = append ( branchNames , branchName )
2021-02-03 22:06:13 +03:00
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 ++
}
2020-12-17 17:00:47 +03:00
}
2021-02-03 22:06:13 +03:00
return branchNames , i , nil
2020-12-17 17:00:47 +03:00
}