aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/object/commitgraph/commitnode.go
blob: d92c9064f729f7c80e2996044ad01c09a1d6e6e6 (plain) (blame)
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
package commitgraph

import (
	"io"
	"time"

	"github.com/go-git/go-git/v5/plumbing"
	"github.com/go-git/go-git/v5/plumbing/object"
	"github.com/go-git/go-git/v5/plumbing/storer"
)

// CommitNode is generic interface encapsulating a lightweight commit object retrieved
// from CommitNodeIndex
type CommitNode interface {
	// ID returns the Commit object id referenced by the commit graph node.
	ID() plumbing.Hash
	// Tree returns the Tree referenced by the commit graph node.
	Tree() (*object.Tree, error)
	// CommitTime returns the Committer.When time of the Commit referenced by the commit graph node.
	CommitTime() time.Time
	// NumParents returns the number of parents in a commit.
	NumParents() int
	// ParentNodes return a CommitNodeIter for parents of specified node.
	ParentNodes() CommitNodeIter
	// ParentNode returns the ith parent of a commit.
	ParentNode(i int) (CommitNode, error)
	// ParentHashes returns hashes of the parent commits for a specified node
	ParentHashes() []plumbing.Hash
	// Generation returns the generation of the commit for reachability analysis.
	// Objects with newer generation are not reachable from objects of older generation.
	Generation() uint64
	// Commit returns the full commit object from the node
	Commit() (*object.Commit, error)
}

// CommitNodeIndex is generic interface encapsulating an index of CommitNode objects
type CommitNodeIndex interface {
	// Get returns a commit node from a commit hash
	Get(hash plumbing.Hash) (CommitNode, error)
}

// CommitNodeIter is a generic closable interface for iterating over commit nodes.
type CommitNodeIter interface {
	Next() (CommitNode, error)
	ForEach(func(CommitNode) error) error
	Close()
}

// parentCommitNodeIter provides an iterator for parent commits from associated CommitNodeIndex.
type parentCommitNodeIter struct {
	node CommitNode
	i    int
}

func newParentgraphCommitNodeIter(node CommitNode) CommitNodeIter {
	return &parentCommitNodeIter{node, 0}
}

// Next moves the iterator to the next commit and returns a pointer to it. If
// there are no more commits, it returns io.EOF.
func (iter *parentCommitNodeIter) Next() (CommitNode, error) {
	obj, err := iter.node.ParentNode(iter.i)
	if err == object.ErrParentNotFound {
		return nil, io.EOF
	}
	if err == nil {
		iter.i++
	}

	return obj, err
}

// ForEach call the cb function for each commit contained on this iter until
// an error appends or the end of the iter is reached. If ErrStop is sent
// the iteration is stopped but no error is returned. The iterator is closed.
func (iter *parentCommitNodeIter) ForEach(cb func(CommitNode) error) error {
	for {
		obj, err := iter.Next()
		if err != nil {
			if err == io.EOF {
				return nil
			}

			return err
		}

		if err := cb(obj); err != nil {
			if err == storer.ErrStop {
				return nil
			}

			return err
		}
	}
}

func (iter *parentCommitNodeIter) Close() {
}