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 FilesAtRef(r *git.Repository, hash plumbing.Hash, path string) ([]NiceTree, error) {
35 c, err := r.CommitObject(hash)
36 if err != nil {
37 return nil, fmt.Errorf("commit object: %w", err)
38 }
39
40 files := []NiceTree{}
41 tree, err := c.Tree()
42 if err != nil {
43 return nil, fmt.Errorf("file tree: %w", err)
44 }
45
46 if path == "" {
47 files = makeNiceTree(tree.Entries)
48 } else {
49 o, err := tree.FindEntry(path)
50 if err != nil {
51 return nil, err
52 }
53
54 if !o.Mode.IsFile() {
55 subtree, err := tree.Tree(path)
56 if err != nil {
57 return nil, err
58 }
59
60 files = makeNiceTree(subtree.Entries)
61 }
62 }
63
64 return files, nil
65}
66
67func FileContentAtRef(r *git.Repository, hash plumbing.Hash, path string) (string, error) {
68 c, err := r.CommitObject(hash)
69 if err != nil {
70 return "", fmt.Errorf("commit object: %w", err)
71 }
72
73 tree, err := c.Tree()
74 if err != nil {
75 return "", fmt.Errorf("file tree: %w", err)
76 }
77
78 file, err := tree.File(path)
79 if err != nil {
80 return "", err
81 }
82
83 return file.Contents()
84}
85
86func makeNiceTree(es []object.TreeEntry) []NiceTree {
87 nts := []NiceTree{}
88 for _, e := range es {
89 mode, _ := e.Mode.ToOSFileMode()
90 nts = append(nts, NiceTree{
91 Name: e.Name,
92 Mode: mode.String(),
93 IsFile: e.Mode.IsFile(),
94 })
95 }
96
97 return nts
98}