summaryrefslogtreecommitdiff
path: root/walk.go
blob: 71df7bb94a2b6f2a3c19b6983fb97683c2ce6fc0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package git

/*
#include <git2.h>
#include <git2/errors.h>
*/
import "C"

import (
	"io"
	"runtime"
)

// RevWalk

type SortType uint

const (
	SortNone        SortType = C.GIT_SORT_NONE
	SortTopological          = C.GIT_SORT_TOPOLOGICAL
	SortTime                 = C.GIT_SORT_TIME
	SortReverse              = C.GIT_SORT_REVERSE
)

type RevWalk struct {
	ptr  *C.git_revwalk
	repo *Repository
}

func revWalkFromC(repo *Repository, c *C.git_revwalk) *RevWalk {
	v := &RevWalk{ptr: c, repo: repo}
	runtime.SetFinalizer(v, (*RevWalk).Free)
	return v
}

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) {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_revwalk_push_head(v.ptr)
	if ecode < 0 {
		err = MakeGitError(ecode)
	}

	return
}

func (v *RevWalk) Next(id *Oid) (err error) {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_revwalk_next(id.toC(), v.ptr)
	switch {
	case ret == ITEROVER:
		err = io.EOF
	case ret < 0:
		err = MakeGitError(ret)
	}

	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 SortType) {
	C.git_revwalk_sorting(v.ptr, C.uint(sm))
}

func (v *RevWalk) Free() {

	runtime.SetFinalizer(v, nil)
	C.git_revwalk_free(v.ptr)
}