git/git.go (view raw)
1package git
2
3import (
4 "fmt"
5
6 "github.com/go-git/go-git/v5"
7 "github.com/go-git/go-git/v5/plumbing"
8 "github.com/go-git/go-git/v5/plumbing/object"
9)
10
11func AllCommits(r *git.Repository) ([]*object.Commit, error) {
12 ci, err := r.Log(&git.LogOptions{All: true})
13 if err != nil {
14 return nil, fmt.Errorf("all commits: %w", err)
15 }
16
17 commits := []*object.Commit{}
18 ci.ForEach(func(c *object.Commit) error {
19 commits = append(commits, c)
20 return nil
21 })
22
23 return commits, nil
24}
25
26// A nicer git tree representation.
27type NiceTree struct {
28 Name string
29 Mode string
30 Size int64
31 IsFile bool
32}
33
34func FilesAtHead(r *git.Repository, path string) ([]NiceTree, error) {
35 head, err := r.Head()
36 if err != nil {
37 return nil, fmt.Errorf("getting head: %w", err)
38 }
39
40 return FilesAtRef(r, head, path)
41}
42
43func FilesAtRef(r *git.Repository, ref *plumbing.Reference, path string) ([]NiceTree, error) {
44 c, err := r.CommitObject(ref.Hash())
45 if err != nil {
46 return nil, fmt.Errorf("commit object: %w", err)
47 }
48
49 files := []NiceTree{}
50 tree, err := c.Tree()
51 if err != nil {
52 return nil, fmt.Errorf("file tree: %w", err)
53 }
54
55 if path == "" {
56 files = makeNiceTree(tree.Entries)
57 } else {
58 o, err := tree.FindEntry(path)
59 if err != nil {
60 return nil, err
61 }
62
63 if !o.Mode.IsFile() {
64 subtree, err := tree.Tree(path)
65 if err != nil {
66 return nil, err
67 }
68
69 files = makeNiceTree(subtree.Entries)
70 }
71 }
72
73 return files, nil
74}
75
76func makeNiceTree(es []object.TreeEntry) []NiceTree {
77 nts := []NiceTree{}
78 for _, e := range es {
79 mode, _ := e.Mode.ToOSFileMode()
80 nts = append(nts, NiceTree{
81 Name: e.Name,
82 Mode: mode.String(),
83 IsFile: e.Mode.IsFile(),
84 })
85 }
86
87 return nts
88}