@ -9,9 +9,10 @@ package git
import (
import (
"bufio"
"bufio"
"errors"
"errors"
"fmt"
"io"
"io"
"io/ioutil"
"io/ioutil"
"os"
"path/filepath"
"strings"
"strings"
)
)
@ -34,6 +35,18 @@ func (repo *Repository) ResolveReference(name string) (string, error) {
// GetRefCommitID returns the last commit ID string of given reference (branch or tag).
// GetRefCommitID returns the last commit ID string of given reference (branch or tag).
func ( repo * Repository ) GetRefCommitID ( name string ) ( string , error ) {
func ( repo * Repository ) GetRefCommitID ( name string ) ( string , error ) {
if strings . HasPrefix ( name , "refs/" ) {
// We're gonna try just reading the ref file as this is likely to be quicker than other options
fileInfo , err := os . Lstat ( filepath . Join ( repo . Path , name ) )
if err == nil && fileInfo . Mode ( ) . IsRegular ( ) && fileInfo . Size ( ) == 41 {
ref , err := ioutil . ReadFile ( filepath . Join ( repo . Path , name ) )
if err == nil && SHAPattern . Match ( ref [ : 40 ] ) && ref [ 40 ] == '\n' {
return string ( ref [ : 40 ] ) , nil
}
}
}
stdout , err := NewCommand ( "show-ref" , "--verify" , "--hash" , name ) . RunInDir ( repo . Path )
stdout , err := NewCommand ( "show-ref" , "--verify" , "--hash" , name ) . RunInDir ( repo . Path )
if err != nil {
if err != nil {
if strings . Contains ( err . Error ( ) , "not a valid ref" ) {
if strings . Contains ( err . Error ( ) , "not a valid ref" ) {
@ -69,6 +82,11 @@ func (repo *Repository) getCommit(id SHA1) (*Commit, error) {
} ( )
} ( )
bufReader := bufio . NewReader ( stdoutReader )
bufReader := bufio . NewReader ( stdoutReader )
return repo . getCommitFromBatchReader ( bufReader , id )
}
func ( repo * Repository ) getCommitFromBatchReader ( bufReader * bufio . Reader , id SHA1 ) ( * Commit , error ) {
_ , typ , size , err := ReadBatchLine ( bufReader )
_ , typ , size , err := ReadBatchLine ( bufReader )
if err != nil {
if err != nil {
if errors . Is ( err , io . EOF ) {
if errors . Is ( err , io . EOF ) {
@ -106,7 +124,6 @@ func (repo *Repository) getCommit(id SHA1) (*Commit, error) {
case "commit" :
case "commit" :
return CommitFromReader ( repo , id , io . LimitReader ( bufReader , size ) )
return CommitFromReader ( repo , id , io . LimitReader ( bufReader , size ) )
default :
default :
_ = stdoutReader . CloseWithError ( fmt . Errorf ( "unknown typ: %s" , typ ) )
log ( "Unknown typ: %s" , typ )
log ( "Unknown typ: %s" , typ )
return nil , ErrNotExist {
return nil , ErrNotExist {
ID : id . String ( ) ,
ID : id . String ( ) ,