1package git
2
3import (
4 "errors"
5 "fmt"
6 "io"
7
8 "github.com/go-git/go-git/v5"
9 "github.com/go-git/go-git/v5/plumbing/object"
10)
11
12var ()
13
14var (
15 MissingHeadErr = errors.New("Head not found")
16)
17
18type (
19 GitRepository struct {
20 path string
21 }
22)
23
24func NewGitRepository(dir string) *GitRepository {
25 return &GitRepository{
26 path: dir,
27 }
28}
29
30func (g *GitRepository) Path() string {
31 return g.path
32}
33
34func (g *GitRepository) LastCommit() (*object.Commit, error) {
35 repo, err := git.PlainOpen(g.path)
36 if err != nil {
37 return nil, err
38 }
39
40 ref, err := repo.Head()
41 if err != nil {
42 return nil, errors.Join(MissingHeadErr, err)
43 }
44
45 c, err := repo.CommitObject(ref.Hash())
46 if err != nil {
47 return nil, err
48 }
49 return c, nil
50}
51
52func (g *GitRepository) Commits() ([]*object.Commit, error) {
53 repo, err := git.PlainOpen(g.path)
54 if err != nil {
55 return nil, err
56 }
57 ref, err := repo.Head()
58 if err != nil {
59 return nil, errors.Join(MissingHeadErr, err)
60 }
61
62 ci, err := repo.Log(&git.LogOptions{From: ref.Hash()})
63 if err != nil {
64 return nil, fmt.Errorf("commits from ref: %w", err)
65 }
66
67 commits := []*object.Commit{}
68 // TODO: for now only load first 1000
69 for x := 0; x < 1000; x++ {
70 c, err := ci.Next()
71 if err != nil && errors.Is(err, io.EOF) {
72 break
73 } else if err != nil {
74 return nil, err
75 }
76 commits = append(commits, c)
77 }
78 if err != nil {
79 return nil, err
80 }
81
82 return commits, nil
83}