forked from toolshed/abra
		
	
		
			
				
	
	
		
			101 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package git
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 
 | |
| 	"coopcloud.tech/abra/pkg/log"
 | |
| 	"github.com/go-git/go-git/v5"
 | |
| 	"github.com/go-git/go-git/v5/plumbing"
 | |
| )
 | |
| 
 | |
| // Check if a branch exists in a repo. Use this and not repository.Branch(),
 | |
| // because the latter does not actually check for existing branches. See
 | |
| // https://github.com/gogit/gogit/issues/518 for more.
 | |
| func HasBranch(repository *git.Repository, name string) bool {
 | |
| 	var exist bool
 | |
| 
 | |
| 	if iter, err := repository.Branches(); err == nil {
 | |
| 		iterFunc := func(reference *plumbing.Reference) error {
 | |
| 			if name == reference.Name().Short() {
 | |
| 				exist = true
 | |
| 				return nil
 | |
| 			}
 | |
| 			return nil
 | |
| 		}
 | |
| 		_ = iter.ForEach(iterFunc)
 | |
| 	}
 | |
| 
 | |
| 	return exist
 | |
| }
 | |
| 
 | |
| // GetCurrentBranch retrieves the current branch of a repository.
 | |
| func GetCurrentBranch(repository *git.Repository) (string, error) {
 | |
| 	branchRefs, err := repository.Branches()
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 
 | |
| 	headRef, err := repository.Head()
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 
 | |
| 	var currentBranchName string
 | |
| 	err = branchRefs.ForEach(func(branchRef *plumbing.Reference) error {
 | |
| 		if branchRef.Hash() == headRef.Hash() {
 | |
| 			currentBranchName = branchRef.Name().String()
 | |
| 
 | |
| 			return nil
 | |
| 		}
 | |
| 
 | |
| 		return nil
 | |
| 	})
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 
 | |
| 	return currentBranchName, nil
 | |
| }
 | |
| 
 | |
| // GetDefaultBranch retrieves the default branch of a repository.
 | |
| func GetDefaultBranch(repo *git.Repository, repoPath string) (plumbing.ReferenceName, error) {
 | |
| 	branch := "master"
 | |
| 
 | |
| 	if !HasBranch(repo, "master") {
 | |
| 		if !HasBranch(repo, "main") {
 | |
| 			return "", fmt.Errorf("failed to select default branch in %s", repoPath)
 | |
| 		}
 | |
| 		branch = "main"
 | |
| 	}
 | |
| 
 | |
| 	return plumbing.ReferenceName(fmt.Sprintf("refs/heads/%s", branch)), nil
 | |
| }
 | |
| 
 | |
| // CheckoutDefaultBranch checks out the default branch of a repository.
 | |
| func CheckoutDefaultBranch(repo *git.Repository, repoPath string) (plumbing.ReferenceName, error) {
 | |
| 	branch, err := GetDefaultBranch(repo, repoPath)
 | |
| 	if err != nil {
 | |
| 		return plumbing.ReferenceName(""), err
 | |
| 	}
 | |
| 
 | |
| 	worktree, err := repo.Worktree()
 | |
| 	if err != nil {
 | |
| 		return plumbing.ReferenceName(""), err
 | |
| 	}
 | |
| 
 | |
| 	checkOutOpts := &git.CheckoutOptions{
 | |
| 		Create: false,
 | |
| 		Force:  true,
 | |
| 		Branch: branch,
 | |
| 	}
 | |
| 
 | |
| 	if err := worktree.Checkout(checkOutOpts); err != nil {
 | |
| 		log.Debugf("failed to check out %s in %s", branch, repoPath)
 | |
| 		return branch, err
 | |
| 	}
 | |
| 
 | |
| 	log.Debugf("successfully checked out %v in %s", branch, repoPath)
 | |
| 
 | |
| 	return branch, nil
 | |
| }
 |