Add branch iterator #66
117
git.go
117
git.go
|
@ -15,14 +15,78 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
type ErrorClass int
|
||||
|
||||
const (
|
||||
ITEROVER = C.GIT_ITEROVER
|
||||
EEXISTS = C.GIT_EEXISTS
|
||||
ENOTFOUND = C.GIT_ENOTFOUND
|
||||
ErrClassNone ErrorClass = C.GITERR_NONE
|
||||
ErrClassNoMemory = C.GITERR_NOMEMORY
|
||||
ErrClassOs = C.GITERR_OS
|
||||
ErrClassInvalid = C.GITERR_INVALID
|
||||
ErrClassReference = C.GITERR_REFERENCE
|
||||
ErrClassZlib = C.GITERR_ZLIB
|
||||
ErrClassRepository = C.GITERR_REPOSITORY
|
||||
ErrClassConfig = C.GITERR_CONFIG
|
||||
ErrClassRegex = C.GITERR_REGEX
|
||||
ErrClassOdb = C.GITERR_ODB
|
||||
ErrClassIndex = C.GITERR_INDEX
|
||||
ErrClassObject = C.GITERR_OBJECT
|
||||
ErrClassNet = C.GITERR_NET
|
||||
ErrClassTag = C.GITERR_TAG
|
||||
ErrClassTree = C.GITERR_TREE
|
||||
ErrClassIndexer = C.GITERR_INDEXER
|
||||
ErrClassSSL = C.GITERR_SSL
|
||||
ErrClassSubmodule = C.GITERR_SUBMODULE
|
||||
ErrClassThread = C.GITERR_THREAD
|
||||
ErrClassStash = C.GITERR_STASH
|
||||
ErrClassCheckout = C.GITERR_CHECKOUT
|
||||
ErrClassFetchHead = C.GITERR_FETCHHEAD
|
||||
ErrClassMerge = C.GITERR_MERGE
|
||||
ErrClassSsh = C.GITERR_SSH
|
||||
ErrClassFilter = C.GITERR_FILTER
|
||||
ErrClassRevert = C.GITERR_REVERT
|
||||
ErrClassCallback = C.GITERR_CALLBACK
|
||||
)
|
||||
|
||||
var (
|
||||
ErrIterOver = errors.New("Iteration is over")
|
||||
type ErrorCode int
|
||||
|
||||
const (
|
||||
|
||||
// No error
|
||||
ErrOk ErrorCode = C.GIT_OK
|
||||
// Generic error
|
||||
ErrGeneric = C.GIT_ERROR
|
||||
// Requested object could not be found
|
||||
ErrNotFound = C.GIT_ENOTFOUND
|
||||
// Object exists preventing operation
|
||||
ErrExists = C.GIT_EEXISTS
|
||||
// More than one object matches
|
||||
ErrAmbigious = C.GIT_EAMBIGUOUS
|
||||
// Output buffer too short to hold data
|
||||
ErrBuffs = C.GIT_EBUFS
|
||||
// GIT_EUSER is a special error that is never generated by libgit2
|
||||
// code. You can return it from a callback (e.g to stop an iteration)
|
||||
// to know that it was generated by the callback and not by libgit2.
|
||||
ErrUser = C.GIT_EUSER
|
||||
// Operation not allowed on bare repository
|
||||
ErrBareRepo = C.GIT_EBAREREPO
|
||||
// HEAD refers to branch with no commits
|
||||
ErrUnbornBranch = C.GIT_EUNBORNBRANCH
|
||||
// Merge in progress prevented operation
|
||||
ErrUnmerged = C.GIT_EUNMERGED
|
||||
// Reference was not fast-forwardable
|
||||
ErrNonFastForward = C.GIT_ENONFASTFORWARD
|
||||
// Name/ref spec was not in a valid format
|
||||
ErrInvalidSpec = C.GIT_EINVALIDSPEC
|
||||
// Merge conflicts prevented operation
|
||||
ErrMergeConflict = C.GIT_EMERGECONFLICT
|
||||
// Lock file prevented operation
|
||||
ErrLocked = C.GIT_ELOCKED
|
||||
// Reference value does not match expected
|
||||
ErrModified = C.GIT_EMODIFIED
|
||||
// Internal only
|
||||
ErrPassthrough = C.GIT_PASSTHROUGH
|
||||
// Signals end of iteration with iterator
|
||||
ErrIterOver = C.GIT_ITEROVER
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -64,6 +128,10 @@ func NewOid(s string) (*Oid, error) {
|
|||
return nil, error
|
||||
}
|
||||
|
||||
if len(slice) != 20 {
|
||||
return nil, &GitError{"Invalid Oid", ErrClassNone, ErrGeneric}
|
||||
}
|
||||
|
||||
copy(o[:], slice[:20])
|
||||
return o, nil
|
||||
}
|
||||
|
@ -125,28 +193,49 @@ func ShortenOids(ids []*Oid, minlen int) (int, error) {
|
|||
|
||||
type GitError struct {
|
||||
Message string
|
||||
Class int
|
||||
ErrorCode int
|
||||
Class ErrorClass
|
||||
Code ErrorCode
|
||||
}
|
||||
|
||||
func (e GitError) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
func IsNotExist(err error) bool {
|
||||
return err.(*GitError).ErrorCode == C.GIT_ENOTFOUND
|
||||
func IsErrorClass(err error, c ErrorClass) bool {
|
||||
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
if gitError, ok := err.(*GitError); ok {
|
||||
return gitError.Class == c
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsExist(err error) bool {
|
||||
return err.(*GitError).ErrorCode == C.GIT_EEXISTS
|
||||
func IsErrorCode(err error, c ErrorCode) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
if gitError, ok := err.(*GitError); ok {
|
||||
return gitError.Code == c
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func MakeGitError(errorCode C.int) error {
|
||||
|
||||
var errMessage string
|
||||
var errClass ErrorClass
|
||||
if errorCode != ErrIterOver {
|
||||
err := C.giterr_last()
|
||||
if err == nil {
|
||||
return &GitError{"No message", C.GITERR_INVALID, C.GIT_ERROR}
|
||||
if err != nil {
|
||||
errMessage = C.GoString(err.message)
|
||||
errClass = ErrorClass(err.klass)
|
||||
} else {
|
||||
errClass = ErrClassInvalid
|
||||
}
|
||||
return &GitError{C.GoString(err.message), int(err.klass), int(errorCode)}
|
||||
}
|
||||
return &GitError{errMessage, errClass, ErrorCode(errorCode)}
|
||||
}
|
||||
|
||||
func MakeGitError2(err int) error {
|
||||
|
|
|
@ -62,3 +62,10 @@ func TestOidZero(t *testing.T) {
|
|||
t.Error("Zero Oid is not zero")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyOid(t *testing.T) {
|
||||
_, err := NewOid("")
|
||||
if err == nil || !IsErrorCode(err, ErrGeneric) {
|
||||
t.Fatal("Should have returned invalid error")
|
||||
}
|
||||
}
|
||||
|
|
4
index.go
4
index.go
|
@ -266,10 +266,6 @@ func (v *IndexConflictIterator) Next() (IndexConflict, error) {
|
|||
defer runtime.UnlockOSThread()
|
||||
|
||||
ecode := C.git_index_conflict_next(&cancestor, &cour, &ctheir, v.ptr)
|
||||
if ecode == C.GIT_ITEROVER {
|
||||
return IndexConflict{}, ErrIterOver
|
||||
}
|
||||
|
||||
if ecode < 0 {
|
||||
return IndexConflict{}, MakeGitError(ecode)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -45,7 +44,6 @@ func Test_Push_ToRemote(t *testing.T) {
|
|||
checkFatal(t, err)
|
||||
|
||||
err = push.StatusForeach(func(ref string, msg string) int {
|
||||
log.Printf("%s -> %s", ref, msg)
|
||||
return 0
|
||||
})
|
||||
checkFatal(t, err)
|
||||
|
|
|
@ -261,9 +261,6 @@ func (v *ReferenceNameIterator) Next() (string, error) {
|
|||
defer runtime.UnlockOSThread()
|
||||
|
||||
ret := C.git_reference_next_name(&ptr, v.ptr)
|
||||
if ret == ITEROVER {
|
||||
return "", ErrIterOver
|
||||
}
|
||||
if ret < 0 {
|
||||
return "", MakeGitError(ret)
|
||||
}
|
||||
|
@ -276,9 +273,6 @@ func (v *ReferenceNameIterator) Next() (string, error) {
|
|||
func (v *ReferenceIterator) Next() (*Reference, error) {
|
||||
var ptr *C.git_reference
|
||||
ret := C.git_reference_next(&ptr, v.ptr)
|
||||
if ret == ITEROVER {
|
||||
return nil, ErrIterOver
|
||||
}
|
||||
if ret < 0 {
|
||||
return nil, MakeGitError(ret)
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ func TestReferenceIterator(t *testing.T) {
|
|||
list = append(list, name)
|
||||
name, err = nameIter.Next()
|
||||
}
|
||||
if err != ErrIterOver {
|
||||
if !IsErrorCode(err, ErrIterOver) {
|
||||
t.Fatal("Iteration not over")
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,7 @@ func TestReferenceIterator(t *testing.T) {
|
|||
count++
|
||||
_, err = iter.Next()
|
||||
}
|
||||
if err != ErrIterOver {
|
||||
if !IsErrorCode(err, ErrIterOver) {
|
||||
t.Fatal("Iteration not over")
|
||||
}
|
||||
|
||||
|
|
5
walk.go
5
walk.go
|
@ -7,7 +7,6 @@ package git
|
|||
import "C"
|
||||
|
||||
import (
|
||||
"io"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
@ -158,8 +157,6 @@ func (v *RevWalk) Next(id *Oid) (err error) {
|
|||
|
||||
ret := C.git_revwalk_next(id.toC(), v.ptr)
|
||||
switch {
|
||||
case ret == ITEROVER:
|
||||
err = io.EOF
|
||||
case ret < 0:
|
||||
err = MakeGitError(ret)
|
||||
}
|
||||
|
@ -173,7 +170,7 @@ func (v *RevWalk) Iterate(fun RevWalkIterator) (err error) {
|
|||
oid := new(Oid)
|
||||
for {
|
||||
err = v.Next(oid)
|
||||
if err == io.EOF {
|
||||
if IsErrorCode(err, ErrIterOver) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue