diff --git a/repository.go b/repository.go index 3b845e7..755926e 100644 --- a/repository.go +++ b/repository.go @@ -81,6 +81,18 @@ func (v *Repository) LookupCommit(o *Oid) (*Commit, error) { return commit, nil } +func (v *Repository) Walk() (*RevWalk, error) { + walk := new(RevWalk) + ecode := C.git_revwalk_new(&walk.ptr, v.ptr) + if ecode < 0 { + return nil, LastError() + } + + walk.repo = v + runtime.SetFinalizer(walk, freeRevWalk) + return walk, nil +} + /* TODO func (v *Repository) Commit( refname string, author, committer *Signature, diff --git a/walk.go b/walk.go new file mode 100644 index 0000000..216eb65 --- /dev/null +++ b/walk.go @@ -0,0 +1,90 @@ +package git + +/* +#cgo pkg-config: libgit2 +#include +#include +*/ +import "C" + +import ( + "io" +) + +// RevWalk + +const ( + SORT_NONE = C.GIT_SORT_NONE + SORT_TOPOLOGICAL = C.GIT_SORT_TOPOLOGICAL + SORT_TIME = C.GIT_SORT_TIME + SORT_REVERSE = C.GIT_SORT_REVERSE +) + +type RevWalk struct { + ptr *C.git_revwalk + repo *Repository +} + +func (v *RevWalk) Reset() { + C.git_revwalk_reset(v.ptr) +} + +func (v *RevWalk) Push(id *Oid) { + C.git_revwalk_push(v.ptr, id.toC()) +} + +func (v *RevWalk) PushHead() (err error) { + ecode := C.git_revwalk_push_head(v.ptr) + if ecode < 0 { + err = LastError() + } + + return +} + +func (v *RevWalk) Next(oid *Oid) (err error) { + ret := C.git_revwalk_next(oid.toC(), v.ptr) + switch { + case ret == ITEROVER: + err = io.EOF + case ret < 0: + err = LastError() + } + + return +} + +type RevWalkIterator func(commit *Commit) bool + +func (v *RevWalk) Iterate(fun RevWalkIterator) (err error) { + oid := new(Oid) + for { + err = v.Next(oid) + if err == io.EOF { + return nil + } + if err != nil { + return err + } + + commit, err := v.repo.LookupCommit(oid) + if err != nil { + return err + } + + cont := fun(commit) + if !cont { + break + } + } + + return nil +} + +func (v *RevWalk) Sorting(sm uint) { + C.git_revwalk_sorting(v.ptr, C.uint(sm)) +} + +func freeRevWalk(walk *RevWalk) { + C.git_revwalk_free(walk.ptr) +}