summaryrefslogtreecommitdiff
path: root/tag.go
diff options
context:
space:
mode:
authorCarlos Martín Nieto <[email protected]>2015-08-31 19:58:29 +0200
committerCarlos Martín Nieto <[email protected]>2015-08-31 19:58:29 +0200
commit6d3a3499f1639a6272e334f9f74b1e0cf6b0bb49 (patch)
tree04b27dfdf1faadcaff6ca40fa27d8edd690045d1 /tag.go
parent157593f38da780c4f6cb6dc61275b9b36a3327bf (diff)
parent4090c401c8bf3f062e898f75bde01e2ef27b3911 (diff)
Merge branch 'master-v23'
Diffstat (limited to 'tag.go')
-rw-r--r--tag.go167
1 files changed, 167 insertions, 0 deletions
diff --git a/tag.go b/tag.go
index 89ac8bd..ca85156 100644
--- a/tag.go
+++ b/tag.go
@@ -2,8 +2,14 @@ package git
/*
#include <git2.h>
+
+extern int _go_git_tag_foreach(git_repository *repo, void *payload);
*/
import "C"
+import (
+ "runtime"
+ "unsafe"
+)
// Tag
type Tag struct {
@@ -42,3 +48,164 @@ func (t Tag) TargetId() *Oid {
func (t Tag) TargetType() ObjectType {
return ObjectType(C.git_tag_target_type(t.cast_ptr))
}
+
+type TagsCollection struct {
+ repo *Repository
+}
+
+func (c *TagsCollection) Create(
+ name string, commit *Commit, tagger *Signature, message string) (*Oid, error) {
+
+ oid := new(Oid)
+
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+
+ cmessage := C.CString(message)
+ defer C.free(unsafe.Pointer(cmessage))
+
+ taggerSig, err := tagger.toC()
+ if err != nil {
+ return nil, err
+ }
+ defer C.git_signature_free(taggerSig)
+
+ ctarget := commit.gitObject.ptr
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ret := C.git_tag_create(oid.toC(), c.repo.ptr, cname, ctarget, taggerSig, cmessage, 0)
+ if ret < 0 {
+ return nil, MakeGitError(ret)
+ }
+
+ return oid, nil
+}
+
+// CreateLightweight creates a new lightweight tag pointing to a commit
+// and returns the id of the target object.
+//
+// The name of the tag is validated for consistency (see git_tag_create() for the rules
+// https://libgit2.github.com/libgit2/#HEAD/group/tag/git_tag_create) and should
+// not conflict with an already existing tag name.
+//
+// If force is true and a reference already exists with the given name, it'll be replaced.
+//
+// The created tag is a simple reference and can be queried using
+// repo.References.Lookup("refs/tags/<name>"). The name of the tag (eg "v1.0.0")
+// is queried with ref.Shorthand().
+func (c *TagsCollection) CreateLightweight(name string, commit *Commit, force bool) (*Oid, error) {
+
+ oid := new(Oid)
+
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+
+ ctarget := commit.gitObject.ptr
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ err := C.git_tag_create_lightweight(oid.toC(), c.repo.ptr, cname, ctarget, cbool(force))
+ if err < 0 {
+ return nil, MakeGitError(err)
+ }
+
+ return oid, nil
+}
+
+// List returns the names of all the tags in the repository,
+// eg: ["v1.0.1", "v2.0.0"].
+func (c *TagsCollection) List() ([]string, error) {
+ var strC C.git_strarray
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ecode := C.git_tag_list(&strC, c.repo.ptr)
+ if ecode < 0 {
+ return nil, MakeGitError(ecode)
+ }
+ defer C.git_strarray_free(&strC)
+
+ tags := makeStringsFromCStrings(strC.strings, int(strC.count))
+ return tags, nil
+}
+
+// ListWithMatch returns the names of all the tags in the repository
+// that match a given pattern.
+//
+// The pattern is a standard fnmatch(3) pattern http://man7.org/linux/man-pages/man3/fnmatch.3.html
+func (c *TagsCollection) ListWithMatch(pattern string) ([]string, error) {
+ var strC C.git_strarray
+
+ patternC := C.CString(pattern)
+ defer C.free(unsafe.Pointer(patternC))
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ecode := C.git_tag_list_match(&strC, patternC, c.repo.ptr)
+ if ecode < 0 {
+ return nil, MakeGitError(ecode)
+ }
+ defer C.git_strarray_free(&strC)
+
+ tags := makeStringsFromCStrings(strC.strings, int(strC.count))
+ return tags, nil
+}
+
+// TagForeachCallback is called for each tag in the repository.
+//
+// The name is the full ref name eg: "refs/tags/v1.0.0".
+//
+// Note that the callback is called for lightweight tags as well,
+// so repo.LookupTag() will return an error for these tags. Use
+// repo.References.Lookup() instead.
+type TagForeachCallback func(name string, id *Oid) error
+type tagForeachData struct {
+ callback TagForeachCallback
+ err error
+}
+
+//export gitTagForeachCb
+func gitTagForeachCb(name *C.char, id *C.git_oid, handle unsafe.Pointer) int {
+ payload := pointerHandles.Get(handle)
+ data, ok := payload.(*tagForeachData)
+ if !ok {
+ panic("could not retrieve tag foreach CB handle")
+ }
+
+ err := data.callback(C.GoString(name), newOidFromC(id))
+ if err != nil {
+ data.err = err
+ return C.GIT_EUSER
+ }
+
+ return 0
+}
+
+// Foreach calls the callback for each tag in the repository.
+func (c *TagsCollection) Foreach(callback TagForeachCallback) error {
+ data := tagForeachData{
+ callback: callback,
+ err: nil,
+ }
+
+ handle := pointerHandles.Track(&data)
+ defer pointerHandles.Untrack(handle)
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ err := C._go_git_tag_foreach(c.repo.ptr, handle)
+ if err == C.GIT_EUSER {
+ return data.err
+ }
+ if err < 0 {
+ return MakeGitError(err)
+ }
+
+ return nil
+}