Add branch iterator #66
117
git.go
117
git.go
|
@ -15,14 +15,78 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ErrorClass int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ITEROVER = C.GIT_ITEROVER
|
ErrClassNone ErrorClass = C.GITERR_NONE
|
||||||
EEXISTS = C.GIT_EEXISTS
|
ErrClassNoMemory = C.GITERR_NOMEMORY
|
||||||
ENOTFOUND = C.GIT_ENOTFOUND
|
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 (
|
type ErrorCode int
|
||||||
ErrIterOver = errors.New("Iteration is over")
|
|
||||||
|
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() {
|
func init() {
|
||||||
|
@ -64,6 +128,10 @@ func NewOid(s string) (*Oid, error) {
|
||||||
return nil, error
|
return nil, error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(slice) != 20 {
|
||||||
|
return nil, &GitError{"Invalid Oid", ErrClassNone, ErrGeneric}
|
||||||
|
}
|
||||||
|
|
||||||
copy(o[:], slice[:20])
|
copy(o[:], slice[:20])
|
||||||
return o, nil
|
return o, nil
|
||||||
}
|
}
|
||||||
|
@ -125,28 +193,49 @@ func ShortenOids(ids []*Oid, minlen int) (int, error) {
|
||||||
|
|
||||||
type GitError struct {
|
type GitError struct {
|
||||||
Message string
|
Message string
|
||||||
Class int
|
Class ErrorClass
|
||||||
ErrorCode int
|
Code ErrorCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e GitError) Error() string {
|
func (e GitError) Error() string {
|
||||||
return e.Message
|
return e.Message
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsNotExist(err error) bool {
|
func IsErrorClass(err error, c ErrorClass) bool {
|
||||||
return err.(*GitError).ErrorCode == C.GIT_ENOTFOUND
|
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if gitError, ok := err.(*GitError); ok {
|
||||||
|
return gitError.Class == c
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsExist(err error) bool {
|
func IsErrorCode(err error, c ErrorCode) bool {
|
||||||
return err.(*GitError).ErrorCode == C.GIT_EEXISTS
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if gitError, ok := err.(*GitError); ok {
|
||||||
|
return gitError.Code == c
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeGitError(errorCode C.int) error {
|
func MakeGitError(errorCode C.int) error {
|
||||||
|
|
||||||
|
var errMessage string
|
||||||
|
var errClass ErrorClass
|
||||||
|
if errorCode != ErrIterOver {
|
||||||
err := C.giterr_last()
|
err := C.giterr_last()
|
||||||
if err == nil {
|
if err != nil {
|
||||||
return &GitError{"No message", C.GITERR_INVALID, C.GIT_ERROR}
|
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 {
|
func MakeGitError2(err int) error {
|
||||||
|
|
|
@ -62,3 +62,10 @@ func TestOidZero(t *testing.T) {
|
||||||
t.Error("Zero Oid is not zero")
|
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()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
ecode := C.git_index_conflict_next(&cancestor, &cour, &ctheir, v.ptr)
|
ecode := C.git_index_conflict_next(&cancestor, &cour, &ctheir, v.ptr)
|
||||||
if ecode == C.GIT_ITEROVER {
|
|
||||||
return IndexConflict{}, ErrIterOver
|
|
||||||
}
|
|
||||||
|
|
||||||
if ecode < 0 {
|
if ecode < 0 {
|
||||||
return IndexConflict{}, MakeGitError(ecode)
|
return IndexConflict{}, MakeGitError(ecode)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -45,7 +44,6 @@ func Test_Push_ToRemote(t *testing.T) {
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
err = push.StatusForeach(func(ref string, msg string) int {
|
err = push.StatusForeach(func(ref string, msg string) int {
|
||||||
log.Printf("%s -> %s", ref, msg)
|
|
||||||
return 0
|
return 0
|
||||||
})
|
})
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
|
@ -261,9 +261,6 @@ func (v *ReferenceNameIterator) Next() (string, error) {
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
ret := C.git_reference_next_name(&ptr, v.ptr)
|
ret := C.git_reference_next_name(&ptr, v.ptr)
|
||||||
if ret == ITEROVER {
|
|
||||||
return "", ErrIterOver
|
|
||||||
}
|
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return "", MakeGitError(ret)
|
return "", MakeGitError(ret)
|
||||||
}
|
}
|
||||||
|
@ -276,9 +273,6 @@ func (v *ReferenceNameIterator) Next() (string, error) {
|
||||||
func (v *ReferenceIterator) Next() (*Reference, error) {
|
func (v *ReferenceIterator) Next() (*Reference, error) {
|
||||||
var ptr *C.git_reference
|
var ptr *C.git_reference
|
||||||
ret := C.git_reference_next(&ptr, v.ptr)
|
ret := C.git_reference_next(&ptr, v.ptr)
|
||||||
if ret == ITEROVER {
|
|
||||||
return nil, ErrIterOver
|
|
||||||
}
|
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return nil, MakeGitError(ret)
|
return nil, MakeGitError(ret)
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ func TestReferenceIterator(t *testing.T) {
|
||||||
list = append(list, name)
|
list = append(list, name)
|
||||||
name, err = nameIter.Next()
|
name, err = nameIter.Next()
|
||||||
}
|
}
|
||||||
if err != ErrIterOver {
|
if !IsErrorCode(err, ErrIterOver) {
|
||||||
t.Fatal("Iteration not over")
|
t.Fatal("Iteration not over")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ func TestReferenceIterator(t *testing.T) {
|
||||||
count++
|
count++
|
||||||
_, err = iter.Next()
|
_, err = iter.Next()
|
||||||
}
|
}
|
||||||
if err != ErrIterOver {
|
if !IsErrorCode(err, ErrIterOver) {
|
||||||
t.Fatal("Iteration not over")
|
t.Fatal("Iteration not over")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
walk.go
5
walk.go
|
@ -7,7 +7,6 @@ package git
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
@ -158,8 +157,6 @@ func (v *RevWalk) Next(id *Oid) (err error) {
|
||||||
|
|
||||||
ret := C.git_revwalk_next(id.toC(), v.ptr)
|
ret := C.git_revwalk_next(id.toC(), v.ptr)
|
||||||
switch {
|
switch {
|
||||||
case ret == ITEROVER:
|
|
||||||
err = io.EOF
|
|
||||||
case ret < 0:
|
case ret < 0:
|
||||||
err = MakeGitError(ret)
|
err = MakeGitError(ret)
|
||||||
}
|
}
|
||||||
|
@ -173,7 +170,7 @@ func (v *RevWalk) Iterate(fun RevWalkIterator) (err error) {
|
||||||
oid := new(Oid)
|
oid := new(Oid)
|
||||||
for {
|
for {
|
||||||
err = v.Next(oid)
|
err = v.Next(oid)
|
||||||
if err == io.EOF {
|
if IsErrorCode(err, ErrIterOver) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue