summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blob.go15
-rw-r--r--checkout.go23
-rw-r--r--clone.go27
-rw-r--r--index.go15
-rw-r--r--repository.go26
-rw-r--r--revparse.go114
-rw-r--r--revparse_test.go58
-rwxr-xr-xscript/build-libgit2-static.sh1
-rwxr-xr-xscript/with-static.sh3
-rw-r--r--tree.go3
m---------vendor/libgit20
11 files changed, 237 insertions, 48 deletions
diff --git a/blob.go b/blob.go
index 4277127..58258fd 100644
--- a/blob.go
+++ b/blob.go
@@ -36,12 +36,21 @@ func (v *Blob) Contents() []byte {
func (repo *Repository) CreateBlobFromBuffer(data []byte) (*Oid, error) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
- oid := C.git_oid{}
- ecode := C.git_blob_create_frombuffer(&oid, repo.ptr, unsafe.Pointer(&data[0]), C.size_t(len(data)))
+
+ var id C.git_oid
+ var ptr unsafe.Pointer
+
+ if len(data) > 0 {
+ ptr = unsafe.Pointer(&data[0])
+ } else {
+ ptr = unsafe.Pointer(nil)
+ }
+
+ ecode := C.git_blob_create_frombuffer(&id, repo.ptr, ptr, C.size_t(len(data)))
if ecode < 0 {
return nil, MakeGitError(ecode)
}
- return newOidFromC(&oid), nil
+ return newOidFromC(&id), nil
}
type BlobChunkCallback func(maxLen int) ([]byte, error)
diff --git a/checkout.go b/checkout.go
index 8974a8c..633303d 100644
--- a/checkout.go
+++ b/checkout.go
@@ -67,14 +67,10 @@ func populateCheckoutOpts(ptr *C.git_checkout_options, opts *CheckoutOpts) *C.gi
// Updates files in the index and the working tree to match the content of
// the commit pointed at by HEAD. opts may be nil.
func (v *Repository) CheckoutHead(opts *CheckoutOpts) error {
- var copts C.git_checkout_options
-
- ptr := populateCheckoutOpts(&copts, opts)
-
runtime.LockOSThread()
defer runtime.UnlockOSThread()
- ret := C.git_checkout_head(v.ptr, ptr)
+ ret := C.git_checkout_head(v.ptr, opts.toC())
if ret < 0 {
return MakeGitError(ret)
}
@@ -86,9 +82,6 @@ func (v *Repository) CheckoutHead(opts *CheckoutOpts) error {
// index. If index is nil, the repository's index will be used. opts
// may be nil.
func (v *Repository) CheckoutIndex(index *Index, opts *CheckoutOpts) error {
- var copts C.git_checkout_options
- ptr := populateCheckoutOpts(&copts, opts)
-
var iptr *C.git_index = nil
if index != nil {
iptr = index.ptr
@@ -97,7 +90,19 @@ func (v *Repository) CheckoutIndex(index *Index, opts *CheckoutOpts) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
- ret := C.git_checkout_index(v.ptr, iptr, ptr)
+ ret := C.git_checkout_index(v.ptr, iptr, opts.toC())
+ if ret < 0 {
+ return MakeGitError(ret)
+ }
+
+ return nil
+}
+
+func (v *Repository) CheckoutTree(tree *Tree, opts *CheckoutOpts) error {
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ret := C.git_checkout_tree(v.ptr, tree.ptr, opts.toC())
if ret < 0 {
return MakeGitError(ret)
}
diff --git a/clone.go b/clone.go
index 1bc3261..4acf170 100644
--- a/clone.go
+++ b/clone.go
@@ -14,10 +14,10 @@ import (
type CloneOptions struct {
*CheckoutOpts
*RemoteCallbacks
- Bare bool
- IgnoreCertErrors bool
- RemoteName string
- CheckoutBranch string
+ Bare bool
+ CheckoutBranch string
+ RemoteCreateCallback C.git_remote_create_cb
+ RemoteCreatePayload unsafe.Pointer
}
func Clone(url string, path string, options *CloneOptions) (*Repository, error) {
@@ -32,12 +32,6 @@ func Clone(url string, path string, options *CloneOptions) (*Repository, error)
var copts C.git_clone_options
populateCloneOptions(&copts, options)
- // finish populating clone options here so we can defer CString free
- if len(options.RemoteName) != 0 {
- copts.remote_name = C.CString(options.RemoteName)
- defer C.free(unsafe.Pointer(copts.remote_name))
- }
-
if len(options.CheckoutBranch) != 0 {
copts.checkout_branch = C.CString(options.CheckoutBranch)
defer C.free(unsafe.Pointer(copts.checkout_branch))
@@ -67,9 +61,14 @@ func populateCloneOptions(ptr *C.git_clone_options, opts *CloneOptions) {
} else {
ptr.bare = 0
}
- if opts.IgnoreCertErrors {
- ptr.ignore_cert_errors = 1
- } else {
- ptr.ignore_cert_errors = 0
+
+ if opts.RemoteCreateCallback != nil {
+ ptr.remote_cb = opts.RemoteCreateCallback
+ defer C.free(unsafe.Pointer(opts.RemoteCreateCallback))
+
+ if opts.RemoteCreatePayload != nil {
+ ptr.remote_cb_payload = opts.RemoteCreatePayload
+ defer C.free(opts.RemoteCreatePayload)
+ }
}
}
diff --git a/index.go b/index.go
index f8ce6b3..b1542d5 100644
--- a/index.go
+++ b/index.go
@@ -114,6 +114,21 @@ func (v *Index) AddByPath(path string) error {
return nil
}
+func (v *Index) RemoveByPath(path string) error {
+ cstr := C.CString(path)
+ defer C.free(unsafe.Pointer(cstr))
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ret := C.git_index_remove_bypath(v.ptr, cstr)
+ if ret < 0 {
+ return MakeGitError(ret)
+ }
+
+ return nil
+}
+
func (v *Index) WriteTreeTo(repo *Repository) (*Oid, error) {
oid := new(Oid)
diff --git a/repository.go b/repository.go
index 8cc966c..09f5fef 100644
--- a/repository.go
+++ b/repository.go
@@ -326,8 +326,13 @@ func (v *Repository) CreateCommit(
oid := new(Oid)
- cref := C.CString(refname)
- defer C.free(unsafe.Pointer(cref))
+ var cref *C.char
+ if refname == "" {
+ cref = nil
+ } else {
+ cref = C.CString(refname)
+ defer C.free(unsafe.Pointer(cref))
+ }
cmsg := C.CString(message)
defer C.free(unsafe.Pointer(cmsg))
@@ -469,23 +474,6 @@ func (v *Repository) TreeBuilderFromTree(tree *Tree) (*TreeBuilder, error) {
return bld, nil
}
-func (v *Repository) RevparseSingle(spec string) (Object, error) {
- cspec := C.CString(spec)
- defer C.free(unsafe.Pointer(cspec))
-
- var ptr *C.git_object
-
- runtime.LockOSThread()
- defer runtime.UnlockOSThread()
-
- ecode := C.git_revparse_single(&ptr, v.ptr, cspec)
- if ecode < 0 {
- return nil, MakeGitError(ecode)
- }
-
- return allocObject(ptr, v), nil
-}
-
// EnsureLog ensures that there is a reflog for the given reference
// name and creates an empty one if necessary.
func (v *Repository) EnsureLog(name string) error {
diff --git a/revparse.go b/revparse.go
new file mode 100644
index 0000000..9e0070e
--- /dev/null
+++ b/revparse.go
@@ -0,0 +1,114 @@
+package git
+
+/*
+#include <git2.h>
+#include <git2/errors.h>
+
+extern void _go_git_revspec_free(git_revspec *revspec);
+*/
+import "C"
+import (
+ "runtime"
+ "unsafe"
+)
+
+type RevparseFlag int
+
+const (
+ RevparseSingle RevparseFlag = C.GIT_REVPARSE_SINGLE
+ RevparseRange = C.GIT_REVPARSE_RANGE
+ RevparseMergeBase = C.GIT_REVPARSE_MERGE_BASE
+)
+
+type Revspec struct {
+ to Object
+ from Object
+ flags RevparseFlag
+}
+
+func (rs *Revspec) To() Object {
+ return rs.to
+}
+
+func (rs *Revspec) From() Object {
+ return rs.from
+}
+
+func (rs *Revspec) Flags() RevparseFlag {
+ return rs.flags
+}
+
+func newRevspecFromC(ptr *C.git_revspec, repo *Repository) *Revspec {
+ var to Object
+ var from Object
+
+ if ptr.to != nil {
+ to = allocObject(ptr.to, repo)
+ }
+
+ if ptr.from != nil {
+ from = allocObject(ptr.from, repo)
+ }
+
+ return &Revspec{
+ to: to,
+ from: from,
+ flags: RevparseFlag(ptr.flags),
+ }
+}
+
+func (r *Repository) Revparse(spec string) (*Revspec, error) {
+ cspec := C.CString(spec)
+ defer C.free(unsafe.Pointer(cspec))
+
+ var crevspec C.git_revspec
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ecode := C.git_revparse(&crevspec, r.ptr, cspec)
+ if ecode != 0 {
+ return nil, MakeGitError(ecode)
+ }
+
+ return newRevspecFromC(&crevspec, r), nil
+}
+
+func (v *Repository) RevparseSingle(spec string) (Object, error) {
+ cspec := C.CString(spec)
+ defer C.free(unsafe.Pointer(cspec))
+
+ var ptr *C.git_object
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ecode := C.git_revparse_single(&ptr, v.ptr, cspec)
+ if ecode < 0 {
+ return nil, MakeGitError(ecode)
+ }
+
+ return allocObject(ptr, v), nil
+}
+
+func (r *Repository) RevparseExt(spec string) (Object, *Reference, error) {
+ cspec := C.CString(spec)
+ defer C.free(unsafe.Pointer(cspec))
+
+ var obj *C.git_object
+ var ref *C.git_reference
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ecode := C.git_revparse_ext(&obj, &ref, r.ptr, cspec)
+ if ecode != 0 {
+ return nil, nil, MakeGitError(ecode)
+ }
+
+ if ref == nil {
+ return allocObject(obj, r), nil, nil
+ }
+
+ return allocObject(obj, r), newReferenceFromC(ref, r), nil
+}
diff --git a/revparse_test.go b/revparse_test.go
new file mode 100644
index 0000000..c046a20
--- /dev/null
+++ b/revparse_test.go
@@ -0,0 +1,58 @@
+package git
+
+import (
+ "os"
+ "testing"
+)
+
+func TestRevparse(t *testing.T) {
+ repo := createTestRepo(t)
+ defer os.RemoveAll(repo.Workdir())
+
+ commitId, _ := seedTestRepo(t, repo)
+
+ revSpec, err := repo.Revparse("HEAD")
+ checkFatal(t, err)
+
+ checkObject(t, revSpec.From(), commitId)
+}
+
+func TestRevparseSingle(t *testing.T) {
+ repo := createTestRepo(t)
+ defer os.RemoveAll(repo.Workdir())
+
+ commitId, _ := seedTestRepo(t, repo)
+
+ obj, err := repo.RevparseSingle("HEAD")
+ checkFatal(t, err)
+
+ checkObject(t, obj, commitId)
+}
+
+func TestRevparseExt(t *testing.T) {
+ repo := createTestRepo(t)
+ defer os.RemoveAll(repo.Workdir())
+
+ _, treeId := seedTestRepo(t, repo)
+
+ ref, err := repo.CreateReference("refs/heads/master", treeId, true, nil, "")
+ checkFatal(t, err)
+
+ obj, ref, err := repo.RevparseExt("master")
+ checkFatal(t, err)
+
+ checkObject(t, obj, treeId)
+ if ref == nil {
+ t.Fatalf("bad reference")
+ }
+}
+
+func checkObject(t *testing.T, obj Object, id *Oid) {
+ if obj == nil {
+ t.Fatalf("bad object")
+ }
+
+ if !obj.Id().Equal(id) {
+ t.Fatalf("bad object, expected %s, got %s", id.String(), obj.Id().String())
+ }
+}
diff --git a/script/build-libgit2-static.sh b/script/build-libgit2-static.sh
index b4d4241..5723721 100755
--- a/script/build-libgit2-static.sh
+++ b/script/build-libgit2-static.sh
@@ -5,6 +5,7 @@ set -ex
VENDORED_PATH=vendor/libgit2
cd $VENDORED_PATH &&
+mkdir -p install/lib &&
mkdir -p build &&
cd build &&
cmake -DTHREADSAFE=ON \
diff --git a/script/with-static.sh b/script/with-static.sh
index 0caed5e..3f60e31 100755
--- a/script/with-static.sh
+++ b/script/with-static.sh
@@ -5,7 +5,8 @@ set -ex
export BUILD="$PWD/vendor/libgit2/build"
export PCFILE="$BUILD/libgit2.pc"
-export CGO_LDFLAGS="$BUILD/libgit2.a -L$BUILD $(pkg-config --static --libs $PCFILE)"
+FLAGS=$(pkg-config --static --libs $PCFILE) || exit 1
+export CGO_LDFLAGS="$BUILD/libgit2.a -L$BUILD ${FLAGS}"
export CGO_CFLAGS="-I$PWD/vendor/libgit2/include"
$@
diff --git a/tree.go b/tree.go
index 8356fba..e5fe361 100644
--- a/tree.go
+++ b/tree.go
@@ -16,8 +16,7 @@ import (
type Filemode int
const (
- FilemodeNew Filemode = C.GIT_FILEMODE_NEW
- FilemodeTree = C.GIT_FILEMODE_TREE
+ FilemodeTree Filemode = C.GIT_FILEMODE_TREE
FilemodeBlob = C.GIT_FILEMODE_BLOB
FilemodeBlobExecutable = C.GIT_FILEMODE_BLOB_EXECUTABLE
FilemodeLink = C.GIT_FILEMODE_LINK
diff --git a/vendor/libgit2 b/vendor/libgit2
-Subproject 28f087c8642ff9c8dd6964e101e6d8539db6281
+Subproject 89e05e2ab19ac452e84e0eaa2dfb8e07ac6839b