all repos — legit @ d58151dbb07a5d5dd7eaf6fc9f12566898823a46

web frontend for git, written in go

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
 11type GitRepo struct {
 12	r *git.Repository
 13	h plumbing.Hash
 14}
 15
 16func Open(path string, ref string) (*GitRepo, error) {
 17	var err error
 18	g := GitRepo{}
 19	g.r, err = git.PlainOpen(path)
 20	if err != nil {
 21		return nil, fmt.Errorf("opening %s: %w", path, err)
 22	}
 23
 24	if ref == "" {
 25		head, err := g.r.Head()
 26		if err != nil {
 27			return nil, fmt.Errorf("getting head of %s: %w", path, err)
 28		}
 29		g.h = head.Hash()
 30	} else {
 31		hash, err := g.r.ResolveRevision(plumbing.Revision(ref))
 32		if err != nil {
 33			return nil, fmt.Errorf("resolving rev %s for %s: %w", ref, path, err)
 34		}
 35		g.h = *hash
 36	}
 37	return &g, nil
 38}
 39
 40func (g *GitRepo) Commits() ([]*object.Commit, error) {
 41	ci, err := g.r.Log(&git.LogOptions{From: g.h})
 42	if err != nil {
 43		return nil, fmt.Errorf("commits from ref: %w", err)
 44	}
 45
 46	commits := []*object.Commit{}
 47	ci.ForEach(func(c *object.Commit) error {
 48		commits = append(commits, c)
 49		return nil
 50	})
 51
 52	return commits, nil
 53}
 54
 55func (g *GitRepo) LastCommit() (*object.Commit, error) {
 56	c, err := g.r.CommitObject(g.h)
 57	if err != nil {
 58		return nil, fmt.Errorf("last commit: %w", err)
 59	}
 60	return c, nil
 61}
 62
 63func (g *GitRepo) FileContent(path string) (string, error) {
 64	c, err := g.r.CommitObject(g.h)
 65	if err != nil {
 66		return "", fmt.Errorf("commit object: %w", err)
 67	}
 68
 69	tree, err := c.Tree()
 70	if err != nil {
 71		return "", fmt.Errorf("file tree: %w", err)
 72	}
 73
 74	file, err := tree.File(path)
 75	if err != nil {
 76		return "", err
 77	}
 78
 79	isbin, _ := file.IsBinary()
 80
 81	if !isbin {
 82		return file.Contents()
 83	} else {
 84		return "Not displaying binary file", nil
 85	}
 86}
 87
 88func (g *GitRepo) Tags() ([]*object.Tag, error) {
 89	ti, err := g.r.TagObjects()
 90	if err != nil {
 91		return nil, fmt.Errorf("tag objects: %w", err)
 92	}
 93
 94	tags := []*object.Tag{}
 95
 96	_ = ti.ForEach(func(t *object.Tag) error {
 97		tags = append(tags, t)
 98		return nil
 99	})
100
101	return tags, nil
102}
103
104func (g *GitRepo) Branches() ([]*plumbing.Reference, error) {
105	bi, err := g.r.Branches()
106	if err != nil {
107		return nil, fmt.Errorf("branchs: %w", err)
108	}
109
110	branches := []*plumbing.Reference{}
111
112	_ = bi.ForEach(func(ref *plumbing.Reference) error {
113		branches = append(branches, ref)
114		return nil
115	})
116
117	return branches, nil
118}
119
120func (g *GitRepo) FindMainBranch(branches []string) (string, error) {
121	for _, b := range branches {
122		_, err := g.r.ResolveRevision(plumbing.Revision(b))
123		if err == nil {
124			return b, nil
125		}
126	}
127	return "", fmt.Errorf("unable to find main branch")
128}