package git import ( "fmt" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/sirupsen/logrus" ) // 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 { logrus.Debugf("failed to check out %s in %s", branch, repoPath) return branch, err } logrus.Debugf("successfully checked out %v in %s", branch, repoPath) return branch, nil }