Merge remote-tracking branch 'upstream/master' into next

This commit is contained in:
Carlos Martín Nieto 2016-02-15 15:02:19 +01:00
commit 6d6736b2bd
12 changed files with 203 additions and 17 deletions

View File

@ -8,7 +8,7 @@ Go bindings for [libgit2](http://libgit2.github.com/). The `master` branch follo
Installing
----------
This project wraps the functionality provided by libgit2. If you're using a stable version, install it to your system via your system's package manaager and then install git2go as usual.
This project wraps the functionality provided by libgit2. If you're using a stable version, install it to your system via your system's package manager and then install git2go as usual.
Otherwise (`next` which tracks an unstable version), we need to build libgit2 as well. In order to build it, you need `cmake`, `pkg-config` and a C compiler. You will also need the development packages for OpenSSL and LibSSH2 installed if you want libgit2 to support HTTPS and SSH respectively.

View File

@ -84,7 +84,7 @@ func (repo *Repository) CreateBlobFromChunks(hintPath string, callback BlobChunk
var chintPath *C.char = nil
if len(hintPath) > 0 {
C.CString(hintPath)
chintPath = C.CString(hintPath)
defer C.free(unsafe.Pointer(chintPath))
}
oid := C.git_oid{}

View File

@ -45,6 +45,7 @@ type CheckoutOpts struct {
FileOpenFlags int // Default is O_CREAT | O_TRUNC | O_WRONLY
TargetDirectory string // Alternative checkout path to workdir
Paths []string
Baseline *Tree
}
func checkoutOptionsFromC(c *C.git_checkout_options) CheckoutOpts {
@ -90,6 +91,10 @@ func populateCheckoutOpts(ptr *C.git_checkout_options, opts *CheckoutOpts) *C.gi
ptr.paths.count = C.size_t(len(opts.Paths))
}
if opts.Baseline != nil {
ptr.baseline = opts.Baseline.cast_ptr
}
return ptr
}

View File

@ -118,18 +118,20 @@ func (c *Config) LookupInt64(name string) (int64, error) {
}
func (c *Config) LookupString(name string) (string, error) {
var ptr *C.char
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
valBuf := C.git_buf{}
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if ret := C.git_config_get_string(&ptr, c.ptr, cname); ret < 0 {
if ret := C.git_config_get_string_buf(&valBuf, c.ptr, cname); ret < 0 {
return "", MakeGitError(ret)
}
defer C.git_buf_free(&valBuf)
return C.GoString(ptr), nil
return C.GoString(valBuf.ptr), nil
}
func (c *Config) LookupBool(name string) (bool, error) {

108
config_test.go Normal file
View File

@ -0,0 +1,108 @@
package git
import (
"os"
"testing"
)
var tempConfig = "./temp.gitconfig"
func setupConfig() (*Config, error) {
var (
c *Config
err error
)
c, err = OpenOndisk(nil, tempConfig)
if err != nil {
return nil, err
}
err = c.SetString("foo.bar", "baz")
if err != nil {
return nil, err
}
err = c.SetBool("foo.bool", true)
if err != nil {
return nil, err
}
err = c.SetInt32("foo.int32", 32)
if err != nil {
return nil, err
}
err = c.SetInt64("foo.int64", 64)
if err != nil {
return nil, err
}
return c, err
}
func cleanupConfig() {
os.Remove(tempConfig)
}
type TestRunner func(*Config, *testing.T)
var tests = []TestRunner{
// LookupString
func(c *Config, t *testing.T) {
val, err := c.LookupString("foo.bar")
if err != nil {
t.Errorf("Got LookupString error: '%v', expected none\n", err)
}
if val != "baz" {
t.Errorf("Got '%s' from LookupString, expected 'bar'\n", val)
}
},
// LookupBool
func(c *Config, t *testing.T) {
val, err := c.LookupBool("foo.bool")
if err != nil {
t.Errorf("Got LookupBool error: '%v', expected none\n", err)
}
if !val {
t.Errorf("Got %b from LookupBool, expected 'false'\n", val)
}
},
// LookupInt32
func(c *Config, t *testing.T) {
val, err := c.LookupInt32("foo.int32")
if err != nil {
t.Errorf("Got LookupInt32 error: '%v', expected none\n", err)
}
if val != 32 {
t.Errorf("Got %v, expected 32\n", val)
}
},
// LookupInt64
func(c *Config, t *testing.T) {
val, err := c.LookupInt64("foo.int64")
if err != nil {
t.Errorf("Got LookupInt64 error: '%v', expected none\n", err)
}
if val != 64 {
t.Errorf("Got %v, expected 64\n", val)
}
},
}
func TestConfigLookups(t *testing.T) {
var (
err error
c *Config
)
c, err = setupConfig()
defer cleanupConfig()
if err != nil {
t.Errorf("Setup error: '%v'. Expected none\n", err)
return
}
defer c.Free()
for _, test := range tests {
test(c, t)
}
}

View File

@ -115,7 +115,7 @@ func NewIndex() (*Index, error) {
return nil, MakeGitError(err)
}
return &Index{ptr: ptr}, nil
return newIndexFromC(ptr), nil
}
// OpenIndex creates a new index at the given path. If the file does
@ -133,7 +133,7 @@ func OpenIndex(path string) (*Index, error) {
return nil, MakeGitError(err)
}
return &Index{ptr: ptr}, nil
return newIndexFromC(ptr), nil
}
// Path returns the index' path on disk or an empty string if it

View File

@ -185,6 +185,9 @@ const (
MergePreferenceFastForwardOnly MergePreference = C.GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY
)
// MergeAnalysis returns the possible actions which could be taken by
// a 'git-merge' command. There may be multiple answers, so the first
// return value is a bitmask of MergeAnalysis values.
func (r *Repository) MergeAnalysis(theirHeads []*AnnotatedCommit) (MergeAnalysis, MergePreference, error) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()

19
odb.go
View File

@ -8,7 +8,6 @@ extern void _go_git_odb_backend_free(git_odb_backend *backend);
*/
import "C"
import (
"fmt"
"reflect"
"runtime"
"unsafe"
@ -55,6 +54,21 @@ func (v *Odb) AddBackend(backend *OdbBackend, priority int) (err error) {
return nil
}
func (v *Odb) ReadHeader(oid *Oid) (uint64, ObjectType, error) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
var sz C.size_t
var cotype C.git_otype
ret := C.git_odb_read_header(&sz, &cotype, v.ptr, oid.toC())
if ret < 0 {
return 0, C.GIT_OBJ_BAD, MakeGitError(ret)
}
return uint64(sz), ObjectType(cotype), nil
}
func (v *Odb) Exists(oid *Oid) bool {
ret := C.git_odb_exists(v.ptr, oid.toC())
return ret != 0
@ -107,9 +121,7 @@ func odbForEachCb(id *C.git_oid, handle unsafe.Pointer) int {
}
err := data.callback(newOidFromC(id))
fmt.Println("err %v", err)
if err != nil {
fmt.Println("returning EUSER")
data.err = err
return C.GIT_EUSER
}
@ -130,7 +142,6 @@ func (v *Odb) ForEach(callback OdbForEachCallback) error {
defer pointerHandles.Untrack(handle)
ret := C._go_git_odb_foreach(v.ptr, handle)
fmt.Println("ret %v", ret)
if ret == C.GIT_EUSER {
return data.err
} else if ret < 0 {

View File

@ -6,6 +6,34 @@ import (
"testing"
)
func TestOdbReadHeader(t *testing.T) {
repo := createTestRepo(t)
defer cleanupTestRepo(t, repo)
_, _ = seedTestRepo(t, repo)
odb, err := repo.Odb()
if err != nil {
t.Fatalf("Odb: %v", err)
}
data := []byte("hello")
id, err := odb.Write(data, ObjectBlob)
if err != nil {
t.Fatalf("odb.Write: %v", err)
}
sz, typ, err := odb.ReadHeader(id)
if err != nil {
t.Fatalf("ReadHeader: %v", err)
}
if sz != uint64(len(data)) {
t.Errorf("ReadHeader got size %d, want %d", sz, len(data))
}
if typ != ObjectBlob {
t.Errorf("ReadHeader got object type %s", typ)
}
}
func TestOdbStream(t *testing.T) {
repo := createTestRepo(t)
defer cleanupTestRepo(t, repo)

View File

@ -637,15 +637,17 @@ func (o *Remote) Fetch(refspecs []string, opts *FetchOptions, msg string) error
crefspecs.strings = makeCStringsFromStrings(refspecs)
defer freeStrarray(&crefspecs)
var coptions C.git_fetch_options
populateFetchOptions(&coptions, opts)
coptions := (*C.git_fetch_options)(C.calloc(1, C.size_t(unsafe.Sizeof(C.git_fetch_options{}))))
defer C.free(unsafe.Pointer(coptions))
populateFetchOptions(coptions, opts)
defer untrackCalbacksPayload(&coptions.callbacks)
defer freeStrarray(&coptions.custom_headers)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_remote_fetch(o.ptr, &crefspecs, &coptions, cmsg)
ret := C.git_remote_fetch(o.ptr, &crefspecs, coptions, cmsg)
if ret < 0 {
return MakeGitError(ret)
}
@ -737,15 +739,17 @@ func (o *Remote) Push(refspecs []string, opts *PushOptions) error {
crefspecs.strings = makeCStringsFromStrings(refspecs)
defer freeStrarray(&crefspecs)
var coptions C.git_push_options
populatePushOptions(&coptions, opts)
coptions := (*C.git_push_options)(C.calloc(1, C.size_t(unsafe.Sizeof(C.git_push_options{}))))
defer C.free(unsafe.Pointer(coptions))
populatePushOptions(coptions, opts)
defer untrackCalbacksPayload(&coptions.callbacks)
defer freeStrarray(&coptions.custom_headers)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_remote_push(o.ptr, &crefspecs, &coptions)
ret := C.git_remote_push(o.ptr, &crefspecs, coptions)
if ret < 0 {
return MakeGitError(ret)
}

View File

@ -447,3 +447,24 @@ func (r *Repository) StateCleanup() error {
}
return nil
}
func (r *Repository) AddGitIgnoreRules(rules string) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
crules := C.CString(rules)
defer C.free(unsafe.Pointer(crules))
if ret := C.git_ignore_add_rule(r.ptr, crules); ret < 0 {
return MakeGitError(ret)
}
return nil
}
func (r *Repository) ClearGitIgnoreRules() error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if ret := C.git_ignore_clear_internal_rules(r.ptr); ret < 0 {
return MakeGitError(ret)
}
return nil
}

View File

@ -194,6 +194,10 @@ func (v *RevWalk) Iterate(fun RevWalkIterator) (err error) {
return nil
}
func (v *RevWalk) SimplifyFirstParent() {
C.git_revwalk_simplify_first_parent(v.ptr)
}
func (v *RevWalk) Sorting(sm SortType) {
C.git_revwalk_sorting(v.ptr, C.uint(sm))
}