Personal Git forge.

Code git clone ssh://git.poy.ooo:6969/~poyo/farga ZIP
lib/git/git.go / 3KiB #62cd2fe8
Raw
package gitimport (	"errors"	"farga/lib"	"fmt"	"os"	"path/filepath"	"strings"	git "github.com/go-git/go-git/v6"	"github.com/go-git/go-git/v6/plumbing"	"github.com/go-git/go-git/v6/plumbing/object"	"github.com/google/uuid")var ErrEmptyRepo = errors.New("git: repository has no branches. (blank repo)")var ErrRepoDoesNotExist = errors.New("git: no such repository exists.")var ErrRepoHasNoBranches = errors.New("git: repository has no branches.")var ErrRepoHasNoHead = errors.New("git: repository has no HEAD.")var ErrInvalidBranch = errors.New("git: no such branch exists.")func RepoPath(user uuid.UUID, repo uuid.UUID) string {	base, err := filepath.Abs(lib.GitReposDir)	if err != nil {		return ""	}	return strings.TrimSuffix(filepath.Join(		base,		user.String(),		repo.String(),	)+"/", ".git")}// creates a git repofunc InitRepo(userID uuid.UUID, repoID uuid.UUID) (*git.Repository, error) {	repoPath := RepoPath(userID, repoID)	// if you want to auto-setup a branch, run:	// plumbedBranch := plumbing.NewBranchReferenceName(branch)	// repo, err := git.PlainInit(repoPath, true, git.WithDefaultBranch(plumbedBranch)) // is a bare repo: https://tms-outsource.com/blog/posts/what-is-a-bare-repository/	repo, err := git.PlainInit(repoPath, true) // is a bare repo: https://tms-outsource.com/blog/posts/what-is-a-bare-repository/	return repo, err}type GitRepo struct {	Git          *git.Repository	Head         *plumbing.Reference	ShortHash    string	LatestCommit *object.Commit	Readme       ReadmeType	Files        []File}// Opens a git repo by the defined branch (branch can be nil to be autoselected as HEAD)func Repo(userID uuid.UUID, repoID uuid.UUID, branch string) (*GitRepo, error) {	path := RepoPath(userID, repoID)	repo, err := git.PlainOpen(path)	if err != nil {		switch err {		case git.ErrRepositoryNotExists:			return nil, ErrRepoDoesNotExist		default:			return nil, err		}	}	head, err := ResolveHead(repo, branch) // potentially nil.	if err != nil && err != ErrRepoHasNoHead {		return nil, err	}	var latestCommit *object.Commit	var shortHash string	var readme ReadmeType	// extra info	if head != nil {		latestCommit, err = object.GetCommit(repo.Storer, head.Hash())		if err != nil {			fmt.Println(err)		} else {			if tree, err := latestCommit.Tree(); err == nil {				readme = Readme(tree)			}			shortHash, err = ShortenHash(head.Hash().String())		}	}	return &GitRepo{		Git:          repo,		ShortHash:    shortHash,		Head:         head,		LatestCommit: latestCommit,		Readme:       readme,	}, nil}// resolves the head of a git repofunc ResolveHead(repo *git.Repository, branchName string) (ref *plumbing.Reference, err error) {	// if a branch was provided	if branchName != "" {		ref, err = repo.Reference(plumbing.NewBranchReferenceName(branchName), false)		if errors.Is(err, plumbing.ErrReferenceNotFound) {			return nil, ErrInvalidBranch // doesn't exist.		}		return ref, nil	}	ref, err = repo.Head() // get HEAD as default	if err != nil {		// no HEAD? fine. I'll do it myself		branches, branchErr := repo.Branches()		if branchErr != nil {			return nil, branchErr // idk man.		}		firstBranch, nextErr := branches.Next()		branches.Close()		if nextErr != nil {			// holy shit there are no branches			return nil, ErrRepoHasNoHead		}		// thank god there's a branch		return firstBranch, nil	}	// just return HEAD	return ref, nil}// gets the tree from a commit.func BaseTree(repo *git.Repository, head *plumbing.Reference) (*object.Tree, error) {	commit, err := object.GetCommit(repo.Storer, head.Hash())	if err != nil {		return nil, err	}	return commit.Tree()}// deletes a repo on-disk.func DeleteRepo(userID uuid.UUID, repoID uuid.UUID) {	os.RemoveAll(RepoPath(userID, repoID))}