From ff5150e6c9a0e9f82eb3c26df96f8839242589ca Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Tue, 8 Oct 2013 02:07:06 +0200 Subject: [PATCH 1/7] branch: Implemented branch functions. --- branch.go | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 branch.go diff --git a/branch.go b/branch.go new file mode 100644 index 0000000..8dd55a3 --- /dev/null +++ b/branch.go @@ -0,0 +1,199 @@ +package git + +/* +#cgo pkg-config: libgit2 +#include +#include +*/ +import "C" + +import ( + "errors" + "strings" + "unsafe" +) + +var ErrEUser = errors.New("Error in user callback function") + +type ListFlags uint + +type BranchT uint + +const ( + BRANCH_LOCAL BranchT = C.GIT_BRANCH_LOCAL + BRANCH_REMOTE = C.GIT_BRANCH_REMOTE +) + +const ( + REFS_DIR = "refs/" + REFS_HEADS_DIR = REFS_DIR + "heads/" + REFS_TAGS_DIR = REFS_DIR + "tags/" + REFS_REMOTES_DIR = REFS_DIR + "remotes/" +) + +type Branch struct { + Reference +} + +func (repo *Repository) BranchCreate(branchName string, target *Commit, force bool) (*Reference, error) { + ref := new(Reference) + cBranchName := C.CString(branchName) + cForce := cbool(force) + err := C.git_branch_create(&ref.ptr, repo.ptr, cBranchName, target.ptr, cForce) + if err < 0 { + return nil, LastError() + } + return ref, nil +} + +func (branch *Branch) BranchDelete() error { + if err := C.git_branch_delete(branch.ptr); err < 0 { + return LastError() + } + return nil +} + +type BranchForeachCB func(name string, flags ListFlags, payload interface{}) error + +func (repo *Repository) BranchForeach(flags ListFlags, callback BranchForeachCB, payload interface{}) error { + iter, err := repo.NewReferenceIterator() + if err != nil { + return err + } + + for { + ref, err := iter.Next() + if err == ErrIterOver { + break + } + + if (flags == ListFlags(BRANCH_LOCAL)) && strings.HasPrefix(ref.Name(), REFS_HEADS_DIR) { + name := strings.TrimPrefix(ref.Name(), REFS_HEADS_DIR) + err = callback(name, ListFlags(BRANCH_LOCAL), payload) + if err != nil { + return err + } + } + + if (flags == ListFlags(BRANCH_REMOTE)) && strings.HasPrefix(ref.Name(), REFS_REMOTES_DIR) { + name := strings.TrimPrefix(ref.Name(), REFS_REMOTES_DIR) + err = callback(name, ListFlags(BRANCH_REMOTE), payload) + if err != nil { + return err + } + } + } + + if err == ErrIterOver { + err = nil + } + return err +} + +func (branch *Branch) Move(newBranchName string, force bool) (*Branch, error) { + newBranch := new(Branch) + cNewBranchName := C.CString(newBranchName) + cForce := cbool(force) + + err := C.git_branch_move(&newBranch.ptr, branch.ptr, cNewBranchName, cForce) + if err < 0 { + return nil, LastError() + } + return newBranch, nil +} + +func (branch *Branch) IsHead() (bool, error) { + isHead := C.git_branch_is_head(branch.ptr) + switch isHead { + case 1: + return true, nil + case 0: + return false, nil + default: + return false, LastError() + } + +} + +func (repo *Repository) BranchLookup(branchName string, branchType BranchT) (*Branch, error) { + branch := new(Branch) + cName := C.CString(branchName) + + err := C.git_branch_lookup(&branch.ptr, repo.ptr, cName, C.git_branch_t(branchType)) + if err < 0 { + return nil, LastError() + } + return branch, nil +} + +func (branch *Branch) Name() (string, error) { + var cName *C.char + defer C.free(unsafe.Pointer(cName)) + + err := C.git_branch_name(&cName, branch.ptr) + if err < 0 { + return "", LastError() + } + + return C.GoString(cName), nil +} + +func (repo *Repository) RemoteName(canonicalBranchName string) (string, error) { + cName := C.CString(canonicalBranchName) + + // Obtain the length of the name + ret := C.git_branch_remote_name(nil, 0, repo.ptr, cName) + if ret < 0 { + return "", LastError() + } + + cBuf := (*C.char)(C.malloc(C.size_t(ret))) + defer C.free(unsafe.Pointer(cBuf)) + + // Actually obtain the name + ret = C.git_branch_remote_name(cBuf, C.size_t(ret), repo.ptr, cName) + if ret < 0 { + return "", LastError() + } + + return C.GoString(cBuf), nil +} + +func (branch *Branch) SetUpstream(upstreamName string) error { + cName := C.CString(upstreamName) + + err := C.git_branch_set_upstream(branch.ptr, cName) + if err < 0 { + return LastError() + } + return nil +} + +func (branch *Branch) Upstream() (*Branch, error) { + upstream := new(Branch) + err := C.git_branch_upstream(&upstream.ptr, branch.ptr) + if err < 0 { + return nil, LastError() + } + return upstream, nil +} + +func (repo *Repository) UpstreamName(canonicalBranchName string) (string, error) { + cName := C.CString(canonicalBranchName) + + // Obtain the length of the name + ret := C.git_branch_upstream_name(nil, 0, repo.ptr, cName) + if ret < 0 { + return "", LastError() + } + + cBuf := (*C.char)(C.malloc(C.size_t(ret))) + defer C.free(unsafe.Pointer(cBuf)) + + // Actually obtain the name + ret = C.git_branch_upstream_name(cBuf, C.size_t(ret), repo.ptr, cName) + if ret < 0 { + return "", LastError() + } + return C.GoString(cBuf), nil +} From f03cec5375d22bda9efebb01e78d9e752ee2b498 Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Tue, 8 Oct 2013 14:39:05 +0200 Subject: [PATCH 2/7] branch: Changed BranchT to BranchType --- branch.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/branch.go b/branch.go index 8dd55a3..651edb2 100644 --- a/branch.go +++ b/branch.go @@ -17,11 +17,11 @@ var ErrEUser = errors.New("Error in user callback function") type ListFlags uint -type BranchT uint +type BranchType uint const ( - BRANCH_LOCAL BranchT = C.GIT_BRANCH_LOCAL - BRANCH_REMOTE = C.GIT_BRANCH_REMOTE + BRANCH_LOCAL BranchType = C.GIT_BRANCH_LOCAL + BRANCH_REMOTE = C.GIT_BRANCH_REMOTE ) const ( @@ -115,7 +115,7 @@ func (branch *Branch) IsHead() (bool, error) { } -func (repo *Repository) BranchLookup(branchName string, branchType BranchT) (*Branch, error) { +func (repo *Repository) BranchLookup(branchName string, branchType BranchType) (*Branch, error) { branch := new(Branch) cName := C.CString(branchName) From 771e0c11bc8b1f00cdd6fdddbfe114957aa77ce2 Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Tue, 8 Oct 2013 14:44:11 +0200 Subject: [PATCH 3/7] branch: Variable names don't repeat its type name any longer --- branch.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/branch.go b/branch.go index 651edb2..e431f07 100644 --- a/branch.go +++ b/branch.go @@ -46,8 +46,8 @@ func (repo *Repository) BranchCreate(branchName string, target *Commit, force bo return ref, nil } -func (branch *Branch) BranchDelete() error { - if err := C.git_branch_delete(branch.ptr); err < 0 { +func (b *Branch) BranchDelete() error { + if err := C.git_branch_delete(b.ptr); err < 0 { return LastError() } return nil @@ -90,20 +90,20 @@ func (repo *Repository) BranchForeach(flags ListFlags, callback BranchForeachCB, return err } -func (branch *Branch) Move(newBranchName string, force bool) (*Branch, error) { +func (b *Branch) Move(newBranchName string, force bool) (*Branch, error) { newBranch := new(Branch) cNewBranchName := C.CString(newBranchName) cForce := cbool(force) - err := C.git_branch_move(&newBranch.ptr, branch.ptr, cNewBranchName, cForce) + err := C.git_branch_move(&newBranch.ptr, b.ptr, cNewBranchName, cForce) if err < 0 { return nil, LastError() } return newBranch, nil } -func (branch *Branch) IsHead() (bool, error) { - isHead := C.git_branch_is_head(branch.ptr) +func (b *Branch) IsHead() (bool, error) { + isHead := C.git_branch_is_head(b.ptr) switch isHead { case 1: return true, nil @@ -115,22 +115,22 @@ func (branch *Branch) IsHead() (bool, error) { } -func (repo *Repository) BranchLookup(branchName string, branchType BranchType) (*Branch, error) { +func (repo *Repository) BranchLookup(branchName string, bt BranchType) (*Branch, error) { branch := new(Branch) cName := C.CString(branchName) - err := C.git_branch_lookup(&branch.ptr, repo.ptr, cName, C.git_branch_t(branchType)) + err := C.git_branch_lookup(&branch.ptr, repo.ptr, cName, C.git_branch_t(bt)) if err < 0 { return nil, LastError() } return branch, nil } -func (branch *Branch) Name() (string, error) { +func (b *Branch) Name() (string, error) { var cName *C.char defer C.free(unsafe.Pointer(cName)) - err := C.git_branch_name(&cName, branch.ptr) + err := C.git_branch_name(&cName, b.ptr) if err < 0 { return "", LastError() } @@ -159,19 +159,19 @@ func (repo *Repository) RemoteName(canonicalBranchName string) (string, error) { return C.GoString(cBuf), nil } -func (branch *Branch) SetUpstream(upstreamName string) error { +func (b *Branch) SetUpstream(upstreamName string) error { cName := C.CString(upstreamName) - err := C.git_branch_set_upstream(branch.ptr, cName) + err := C.git_branch_set_upstream(b.ptr, cName) if err < 0 { return LastError() } return nil } -func (branch *Branch) Upstream() (*Branch, error) { +func (b *Branch) Upstream() (*Branch, error) { upstream := new(Branch) - err := C.git_branch_upstream(&upstream.ptr, branch.ptr) + err := C.git_branch_upstream(&upstream.ptr, b.ptr) if err < 0 { return nil, LastError() } From 6372ec052fb752122bc0662783b8450bbe2ce983 Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Tue, 8 Oct 2013 14:49:03 +0200 Subject: [PATCH 4/7] branch: Renamed BranchCreate to CreateBranch --- branch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/branch.go b/branch.go index e431f07..7a4e4cb 100644 --- a/branch.go +++ b/branch.go @@ -35,7 +35,7 @@ type Branch struct { Reference } -func (repo *Repository) BranchCreate(branchName string, target *Commit, force bool) (*Reference, error) { +func (repo *Repository) CreateBranch(branchName string, target *Commit, force bool) (*Reference, error) { ref := new(Reference) cBranchName := C.CString(branchName) cForce := cbool(force) From 4c4da3a84621cc57e90bfe55b16342796c80aceb Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Tue, 8 Oct 2013 14:52:22 +0200 Subject: [PATCH 5/7] branch: Renamed BranchLookup to LookupBrnach --- branch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/branch.go b/branch.go index 7a4e4cb..07f3f41 100644 --- a/branch.go +++ b/branch.go @@ -115,7 +115,7 @@ func (b *Branch) IsHead() (bool, error) { } -func (repo *Repository) BranchLookup(branchName string, bt BranchType) (*Branch, error) { +func (repo *Repository) LookupBranch(branchName string, bt BranchType) (*Branch, error) { branch := new(Branch) cName := C.CString(branchName) From ed86064871639a956beb5592dc5b64e3d536f882 Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Thu, 10 Oct 2013 10:39:49 +0200 Subject: [PATCH 6/7] branch:BranchForeach: Correct handling of the ListFlags --- branch.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/branch.go b/branch.go index 07f3f41..11e12da 100644 --- a/branch.go +++ b/branch.go @@ -15,10 +15,10 @@ import ( var ErrEUser = errors.New("Error in user callback function") -type ListFlags uint - type BranchType uint +type ListFlags BranchType + const ( BRANCH_LOCAL BranchType = C.GIT_BRANCH_LOCAL BRANCH_REMOTE = C.GIT_BRANCH_REMOTE @@ -62,12 +62,18 @@ func (repo *Repository) BranchForeach(flags ListFlags, callback BranchForeachCB, } for { + var branchLocal bool + var branchRemote bool + ref, err := iter.Next() if err == ErrIterOver { break } - if (flags == ListFlags(BRANCH_LOCAL)) && strings.HasPrefix(ref.Name(), REFS_HEADS_DIR) { + if flags&ListFlags(BRANCH_LOCAL) > 0 { + branchLocal = true + } + if branchLocal && strings.HasPrefix(ref.Name(), REFS_HEADS_DIR) { name := strings.TrimPrefix(ref.Name(), REFS_HEADS_DIR) err = callback(name, ListFlags(BRANCH_LOCAL), payload) if err != nil { @@ -75,7 +81,10 @@ func (repo *Repository) BranchForeach(flags ListFlags, callback BranchForeachCB, } } - if (flags == ListFlags(BRANCH_REMOTE)) && strings.HasPrefix(ref.Name(), REFS_REMOTES_DIR) { + if flags&ListFlags(BRANCH_REMOTE) > 0 { + branchRemote = true + } + if branchRemote && strings.HasPrefix(ref.Name(), REFS_REMOTES_DIR) { name := strings.TrimPrefix(ref.Name(), REFS_REMOTES_DIR) err = callback(name, ListFlags(BRANCH_REMOTE), payload) if err != nil { From 961db94aa21da58a77968099c6b97890e6235d10 Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Wed, 30 Oct 2013 15:01:08 +0100 Subject: [PATCH 7/7] branch: Deleted BranchForeach --- branch.go | 52 ---------------------------------------------------- 1 file changed, 52 deletions(-) diff --git a/branch.go b/branch.go index 11e12da..d30748f 100644 --- a/branch.go +++ b/branch.go @@ -8,17 +8,11 @@ package git import "C" import ( - "errors" - "strings" "unsafe" ) -var ErrEUser = errors.New("Error in user callback function") - type BranchType uint -type ListFlags BranchType - const ( BRANCH_LOCAL BranchType = C.GIT_BRANCH_LOCAL BRANCH_REMOTE = C.GIT_BRANCH_REMOTE @@ -53,52 +47,6 @@ func (b *Branch) BranchDelete() error { return nil } -type BranchForeachCB func(name string, flags ListFlags, payload interface{}) error - -func (repo *Repository) BranchForeach(flags ListFlags, callback BranchForeachCB, payload interface{}) error { - iter, err := repo.NewReferenceIterator() - if err != nil { - return err - } - - for { - var branchLocal bool - var branchRemote bool - - ref, err := iter.Next() - if err == ErrIterOver { - break - } - - if flags&ListFlags(BRANCH_LOCAL) > 0 { - branchLocal = true - } - if branchLocal && strings.HasPrefix(ref.Name(), REFS_HEADS_DIR) { - name := strings.TrimPrefix(ref.Name(), REFS_HEADS_DIR) - err = callback(name, ListFlags(BRANCH_LOCAL), payload) - if err != nil { - return err - } - } - - if flags&ListFlags(BRANCH_REMOTE) > 0 { - branchRemote = true - } - if branchRemote && strings.HasPrefix(ref.Name(), REFS_REMOTES_DIR) { - name := strings.TrimPrefix(ref.Name(), REFS_REMOTES_DIR) - err = callback(name, ListFlags(BRANCH_REMOTE), payload) - if err != nil { - return err - } - } - } - - if err == ErrIterOver { - err = nil - } - return err -} - func (b *Branch) Move(newBranchName string, force bool) (*Branch, error) { newBranch := new(Branch) cNewBranchName := C.CString(newBranchName)