mirror of
https://github.com/grdl/git-get.git
synced 2026-02-04 14:31:49 +00:00
Add a basic branch status parser
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
# git-get
|
||||
|
||||
`git get` - a better way to clone and manage git repositories.
|
||||
|
||||
## Build
|
||||
|
||||
How to build with `libgit2` statically linked into a single executable without dependencies:
|
||||
|
||||
58
branch.go
58
branch.go
@@ -1,8 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
git "github.com/libgit2/git2go/v30"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -13,24 +11,58 @@ type BranchStatus struct {
|
||||
HasUpstream bool
|
||||
NeedsPull bool
|
||||
NeedsPush bool
|
||||
Ahead int
|
||||
Behind int
|
||||
}
|
||||
|
||||
func Branches(repo *git.Repository) ([]*git.Branch, error) {
|
||||
it, err := repo.NewBranchIterator(git.BranchAll)
|
||||
func Branches(repo *git.Repository) ([]BranchStatus, error) {
|
||||
iter, err := repo.NewBranchIterator(git.BranchAll)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed creating branch iterator")
|
||||
}
|
||||
|
||||
it.ForEach(func(branch *git.Branch, branchType git.BranchType) error {
|
||||
fmt.Print(branch.IsRemote())
|
||||
upstream, err := branch.Upstream()
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
} else {
|
||||
fmt.Println(upstream.Name())
|
||||
}
|
||||
var branches []*git.Branch
|
||||
err = iter.ForEach(func(branch *git.Branch, branchType git.BranchType) error {
|
||||
branches = append(branches, branch)
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil, nil
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed iterating over branches")
|
||||
}
|
||||
|
||||
var statuses []BranchStatus
|
||||
for _, branch := range branches {
|
||||
status, err := NewBranchStatus(branch)
|
||||
if err != nil {
|
||||
// TODO: handle error
|
||||
continue
|
||||
}
|
||||
statuses = append(statuses, status)
|
||||
}
|
||||
|
||||
return statuses, nil
|
||||
}
|
||||
|
||||
func NewBranchStatus(branch *git.Branch) (BranchStatus, error) {
|
||||
var status BranchStatus
|
||||
|
||||
name, err := branch.Name()
|
||||
if err != nil {
|
||||
return status, errors.Wrap(err, "Failed getting branch name")
|
||||
}
|
||||
status.Name = name
|
||||
|
||||
status.IsRemote = branch.IsRemote()
|
||||
|
||||
_, err = branch.Upstream()
|
||||
if err != nil {
|
||||
if git.IsErrorCode(err, git.ErrNotFound) {
|
||||
status.HasUpstream = false
|
||||
} else {
|
||||
return status, errors.Wrap(err, "Failed getting branch upstream")
|
||||
}
|
||||
}
|
||||
|
||||
return status, nil
|
||||
}
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
git "github.com/libgit2/git2go/v30"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func TestBranches(t *testing.T) {
|
||||
repo, err := git.OpenRepository("/home/grdl/workspace/gitlab.com/grdl/git-get")
|
||||
checkFatal(t, err)
|
||||
func TestNewBranch(t *testing.T) {
|
||||
repo := newTestRepo(t)
|
||||
|
||||
branches, err := Branches(repo)
|
||||
checkFatal(t, err)
|
||||
createFile(t, repo, "file")
|
||||
stageFile(t, repo, "file")
|
||||
createCommit(t, repo, "Initial commit")
|
||||
branch := createBranch(t, repo, "branch")
|
||||
|
||||
fmt.Println(len(branches))
|
||||
status, err := NewBranchStatus(branch)
|
||||
checkFatal(t, errors.Wrap(err, "Failed getting branch status"))
|
||||
|
||||
if status.Name != "branch" {
|
||||
t.Errorf("Wrong branch name, got %s; want %s", status.Name, "branch")
|
||||
}
|
||||
|
||||
if status.IsRemote != false {
|
||||
t.Errorf("Branch should be local")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ func stageFile(t *testing.T, repo *git.Repository, name string) {
|
||||
checkFatal(t, errors.Wrap(err, "Failed writing index"))
|
||||
}
|
||||
|
||||
func createCommit(t *testing.T, repo *git.Repository, message string) {
|
||||
func createCommit(t *testing.T, repo *git.Repository, message string) *git.Commit {
|
||||
index, err := repo.Index()
|
||||
checkFatal(t, errors.Wrap(err, "Failed getting repo index"))
|
||||
|
||||
@@ -74,6 +74,7 @@ func createCommit(t *testing.T, repo *git.Repository, message string) {
|
||||
empty, err := repo.IsEmpty()
|
||||
checkFatal(t, errors.Wrap(err, "Failed checking if repo is empty"))
|
||||
|
||||
var commitId *git.Oid
|
||||
if !empty {
|
||||
currentBranch, err := repo.Head()
|
||||
checkFatal(t, errors.Wrap(err, "Failed getting current branch"))
|
||||
@@ -81,10 +82,26 @@ func createCommit(t *testing.T, repo *git.Repository, message string) {
|
||||
currentTip, err := repo.LookupCommit(currentBranch.Target())
|
||||
checkFatal(t, errors.Wrap(err, "Failed getting current tip"))
|
||||
|
||||
_, err = repo.CreateCommit("HEAD", signature, signature, message, tree, currentTip)
|
||||
commitId, err = repo.CreateCommit("HEAD", signature, signature, message, tree, currentTip)
|
||||
} else {
|
||||
_, err = repo.CreateCommit("HEAD", signature, signature, message, tree)
|
||||
commitId, err = repo.CreateCommit("HEAD", signature, signature, message, tree)
|
||||
}
|
||||
|
||||
checkFatal(t, errors.Wrap(err, "Failed creating a commit"))
|
||||
commit, err := repo.LookupCommit(commitId)
|
||||
checkFatal(t, errors.Wrap(err, "Failed looking up a commit"))
|
||||
|
||||
return commit
|
||||
}
|
||||
|
||||
func createBranch(t *testing.T, repo *git.Repository, name string) *git.Branch {
|
||||
head, err := repo.Head()
|
||||
checkFatal(t, errors.Wrap(err, "Failed getting repo head"))
|
||||
|
||||
commit, err := repo.LookupCommit(head.Target())
|
||||
checkFatal(t, errors.Wrap(err, "Failed getting commit id from head"))
|
||||
|
||||
branch, err := repo.CreateBranch(name, commit, false)
|
||||
checkFatal(t, errors.Wrap(err, "Failed creating branch"))
|
||||
|
||||
return branch
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user