Merge pull request #351 from ezwiebel/index-remove-directory

Implement git_index_remove_directory in index wrapper
diff --git a/.travis.yml b/.travis.yml
index f796389..79ad168 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,6 +10,8 @@
   - 1.3
   - 1.4
   - 1.5
+  - 1.6
+  - 1.7
   - tip
 
 matrix:
diff --git a/blame_test.go b/blame_test.go
index a2a4d38..ec96af7 100644
--- a/blame_test.go
+++ b/blame_test.go
@@ -6,6 +6,7 @@
 )
 
 func TestBlame(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/blob.go b/blob.go
index 1a86e60..8b3e94f 100644
--- a/blob.go
+++ b/blob.go
@@ -37,15 +37,24 @@
 	defer runtime.UnlockOSThread()
 
 	var id C.git_oid
-	var ptr unsafe.Pointer
+	var size C.size_t
 
+	// Go 1.6 added some increased checking of passing pointer to
+	// C, but its check depends on its expectations of waht we
+	// pass to the C function, so unless we take the address of
+	// its contents at the call site itself, it can fail when
+	// 'data' is a slice of a slice.
+	//
+	// When we're given an empty slice, create a dummy one where 0
+	// isn't out of bounds.
 	if len(data) > 0 {
-		ptr = unsafe.Pointer(&data[0])
+		size = C.size_t(len(data))
 	} else {
-		ptr = unsafe.Pointer(nil)
+		data = []byte{0}
+		size = C.size_t(0)
 	}
 
-	ecode := C.git_blob_create_frombuffer(&id, repo.ptr, ptr, C.size_t(len(data)))
+	ecode := C.git_blob_create_frombuffer(&id, repo.ptr, unsafe.Pointer(&data[0]), size)
 	if ecode < 0 {
 		return nil, MakeGitError(ecode)
 	}
diff --git a/blob_test.go b/blob_test.go
index 2b5ec4f..815ab3d 100644
--- a/blob_test.go
+++ b/blob_test.go
@@ -1,10 +1,23 @@
 package git
 
 import (
+	"bytes"
 	"testing"
 )
 
+type bufWrapper struct {
+	buf     [64]byte
+	pointer []byte
+}
+
+func doublePointerBytes() []byte {
+	o := &bufWrapper{}
+	o.pointer = o.buf[0:10]
+	return o.pointer[0:1]
+}
+
 func TestCreateBlobFromBuffer(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -14,4 +27,16 @@
 	if id.String() != "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391" {
 		t.Fatal("Empty buffer did not deliver empty blob id")
 	}
+
+	for _, data := range []([]byte){[]byte("hello there"), doublePointerBytes()} {
+		id, err = repo.CreateBlobFromBuffer(data)
+		checkFatal(t, err)
+
+		blob, err := repo.LookupBlob(id)
+		checkFatal(t, err)
+		if !bytes.Equal(blob.Contents(), data) {
+			t.Fatal("Loaded bytes don't match original bytes:",
+				blob.Contents(), "!=", data)
+		}
+	}
 }
diff --git a/branch.go b/branch.go
index df72dba..d381c23 100644
--- a/branch.go
+++ b/branch.go
@@ -13,6 +13,7 @@
 type BranchType uint
 
 const (
+	BranchAll    BranchType = C.GIT_BRANCH_ALL
 	BranchLocal  BranchType = C.GIT_BRANCH_LOCAL
 	BranchRemote BranchType = C.GIT_BRANCH_REMOTE
 )
@@ -72,6 +73,10 @@
 		}
 	}
 
+	if err != nil && IsErrorCode(err, ErrIterOver) {
+		return nil
+	}
+
 	return err
 }
 
diff --git a/branch_test.go b/branch_test.go
index a0834a8..01a2e28 100644
--- a/branch_test.go
+++ b/branch_test.go
@@ -5,6 +5,7 @@
 )
 
 func TestBranchIterator(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -27,6 +28,7 @@
 }
 
 func TestBranchIteratorEach(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/checkout.go b/checkout.go
index a2e312b..f5822c9 100644
--- a/checkout.go
+++ b/checkout.go
@@ -2,6 +2,8 @@
 
 /*
 #include <git2.h>
+
+extern void _go_git_populate_checkout_cb(git_checkout_options *opts);
 */
 import "C"
 import (
@@ -10,9 +12,18 @@
 	"unsafe"
 )
 
+type CheckoutNotifyType uint
 type CheckoutStrategy uint
 
 const (
+	CheckoutNotifyNone      CheckoutNotifyType = C.GIT_CHECKOUT_NOTIFY_NONE
+	CheckoutNotifyConflict  CheckoutNotifyType = C.GIT_CHECKOUT_NOTIFY_CONFLICT
+	CheckoutNotifyDirty     CheckoutNotifyType = C.GIT_CHECKOUT_NOTIFY_DIRTY
+	CheckoutNotifyUpdated   CheckoutNotifyType = C.GIT_CHECKOUT_NOTIFY_UPDATED
+	CheckoutNotifyUntracked CheckoutNotifyType = C.GIT_CHECKOUT_NOTIFY_UNTRACKED
+	CheckoutNotifyIgnored   CheckoutNotifyType = C.GIT_CHECKOUT_NOTIFY_IGNORED
+	CheckoutNotifyAll       CheckoutNotifyType = C.GIT_CHECKOUT_NOTIFY_ALL
+
 	CheckoutNone                      CheckoutStrategy = C.GIT_CHECKOUT_NONE                         // Dry run, no actual updates
 	CheckoutSafe                      CheckoutStrategy = C.GIT_CHECKOUT_SAFE                         // Allow safe updates that cannot overwrite uncommitted data
 	CheckoutForce                     CheckoutStrategy = C.GIT_CHECKOUT_FORCE                        // Allow all updates to force working directory to look like index
@@ -37,15 +48,21 @@
 	CheckoutUpdateSubmodulesIfChanged CheckoutStrategy = C.GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED // Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED)
 )
 
+type CheckoutNotifyCallback func(why CheckoutNotifyType, path string, baseline, target, workdir DiffFile) ErrorCode
+type CheckoutProgressCallback func(path string, completed, total uint) ErrorCode
+
 type CheckoutOpts struct {
-	Strategy        CheckoutStrategy // Default will be a dry run
-	DisableFilters  bool             // Don't apply filters like CRLF conversion
-	DirMode         os.FileMode      // Default is 0755
-	FileMode        os.FileMode      // Default is 0644 or 0755 as dictated by blob
-	FileOpenFlags   int              // Default is O_CREAT | O_TRUNC | O_WRONLY
-	TargetDirectory string           // Alternative checkout path to workdir
-	Paths           []string
-	Baseline        *Tree
+	Strategy         CheckoutStrategy   // Default will be a dry run
+	DisableFilters   bool               // Don't apply filters like CRLF conversion
+	DirMode          os.FileMode        // Default is 0755
+	FileMode         os.FileMode        // Default is 0644 or 0755 as dictated by blob
+	FileOpenFlags    int                // Default is O_CREAT | O_TRUNC | O_WRONLY
+	NotifyFlags      CheckoutNotifyType // Default will be none
+	NotifyCallback   CheckoutNotifyCallback
+	ProgressCallback CheckoutProgressCallback
+	TargetDirectory  string // Alternative checkout path to workdir
+	Paths            []string
+	Baseline         *Tree
 }
 
 func checkoutOptionsFromC(c *C.git_checkout_options) CheckoutOpts {
@@ -55,6 +72,13 @@
 	opts.DirMode = os.FileMode(c.dir_mode)
 	opts.FileMode = os.FileMode(c.file_mode)
 	opts.FileOpenFlags = int(c.file_open_flags)
+	opts.NotifyFlags = CheckoutNotifyType(c.notify_flags)
+	if c.notify_payload != nil {
+		opts.NotifyCallback = pointerHandles.Get(c.notify_payload).(*CheckoutOpts).NotifyCallback
+	}
+	if c.progress_payload != nil {
+		opts.ProgressCallback = pointerHandles.Get(c.progress_payload).(*CheckoutOpts).ProgressCallback
+	}
 	if c.target_directory != nil {
 		opts.TargetDirectory = C.GoString(c.target_directory)
 	}
@@ -70,6 +94,38 @@
 	return &c
 }
 
+//export checkoutNotifyCallback
+func checkoutNotifyCallback(why C.git_checkout_notify_t, cpath *C.char, cbaseline, ctarget, cworkdir, data unsafe.Pointer) int {
+	if data == nil {
+		return 0
+	}
+	path := C.GoString(cpath)
+	var baseline, target, workdir DiffFile
+	if cbaseline != nil {
+		baseline = diffFileFromC((*C.git_diff_file)(cbaseline))
+	}
+	if ctarget != nil {
+		target = diffFileFromC((*C.git_diff_file)(ctarget))
+	}
+	if cworkdir != nil {
+		workdir = diffFileFromC((*C.git_diff_file)(cworkdir))
+	}
+	opts := pointerHandles.Get(data).(*CheckoutOpts)
+	if opts.NotifyCallback == nil {
+		return 0
+	}
+	return int(opts.NotifyCallback(CheckoutNotifyType(why), path, baseline, target, workdir))
+}
+
+//export checkoutProgressCallback
+func checkoutProgressCallback(path *C.char, completed_steps, total_steps C.size_t, data unsafe.Pointer) int {
+	opts := pointerHandles.Get(data).(*CheckoutOpts)
+	if opts.ProgressCallback == nil {
+		return 0
+	}
+	return int(opts.ProgressCallback(C.GoString(path), uint(completed_steps), uint(total_steps)))
+}
+
 // Convert the CheckoutOpts struct to the corresponding
 // C-struct. Returns a pointer to ptr, or nil if opts is nil, in order
 // to help with what to pass.
@@ -83,6 +139,17 @@
 	ptr.disable_filters = cbool(opts.DisableFilters)
 	ptr.dir_mode = C.uint(opts.DirMode.Perm())
 	ptr.file_mode = C.uint(opts.FileMode.Perm())
+	ptr.notify_flags = C.uint(opts.NotifyFlags)
+	if opts.NotifyCallback != nil || opts.ProgressCallback != nil {
+		C._go_git_populate_checkout_cb(ptr)
+	}
+	payload := pointerHandles.Track(opts)
+	if opts.NotifyCallback != nil {
+		ptr.notify_payload = payload
+	}
+	if opts.ProgressCallback != nil {
+		ptr.progress_payload = payload
+	}
 	if opts.TargetDirectory != "" {
 		ptr.target_directory = C.CString(opts.TargetDirectory)
 	}
@@ -106,6 +173,9 @@
 	if ptr.paths.count > 0 {
 		freeStrarray(&ptr.paths)
 	}
+	if ptr.notify_payload != nil {
+		pointerHandles.Untrack(ptr.notify_payload)
+	}
 }
 
 // Updates files in the index and the working tree to match the content of
diff --git a/cherrypick_test.go b/cherrypick_test.go
index a3246bd..bfa5ca8 100644
--- a/cherrypick_test.go
+++ b/cherrypick_test.go
@@ -33,6 +33,7 @@
 }
 
 func TestCherrypick(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/clone.go b/clone.go
index e80d14d..1ff5124 100644
--- a/clone.go
+++ b/clone.go
@@ -41,7 +41,6 @@
 
 	var ptr *C.git_repository
 	ret := C.git_clone(&ptr, curl, cpath, copts)
-	freeCheckoutOpts(&copts.checkout_opts)
 
 	if ret < 0 {
 		return nil, MakeGitError(ret)
diff --git a/clone_test.go b/clone_test.go
index a6bbf94..24c3a09 100644
--- a/clone_test.go
+++ b/clone_test.go
@@ -10,6 +10,7 @@
 )
 
 func TestClone(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -35,6 +36,7 @@
 }
 
 func TestCloneWithCallback(t *testing.T) {
+	t.Parallel()
 	testPayload := 0
 
 	repo := createTestRepo(t)
diff --git a/config_test.go b/config_test.go
index fea8d8a..f31e73e 100644
--- a/config_test.go
+++ b/config_test.go
@@ -88,6 +88,7 @@
 }
 
 func TestConfigLookups(t *testing.T) {
+	t.Parallel()
 	var (
 		err error
 		c   *Config
diff --git a/credentials.go b/credentials.go
index bb0ec41..4e42b6e 100644
--- a/credentials.go
+++ b/credentials.go
@@ -44,13 +44,15 @@
 	return int(ret), cred
 }
 
-func NewCredSshKey(username string, publickey string, privatekey string, passphrase string) (int, Cred) {
+// NewCredSshKey creates new ssh credentials reading the public and private keys
+// from the file system.
+func NewCredSshKey(username string, publicKeyPath string, privateKeyPath string, passphrase string) (int, Cred) {
 	cred := Cred{}
 	cusername := C.CString(username)
 	defer C.free(unsafe.Pointer(cusername))
-	cpublickey := C.CString(publickey)
+	cpublickey := C.CString(publicKeyPath)
 	defer C.free(unsafe.Pointer(cpublickey))
-	cprivatekey := C.CString(privatekey)
+	cprivatekey := C.CString(privateKeyPath)
 	defer C.free(unsafe.Pointer(cprivatekey))
 	cpassphrase := C.CString(passphrase)
 	defer C.free(unsafe.Pointer(cpassphrase))
@@ -58,6 +60,22 @@
 	return int(ret), cred
 }
 
+// NewCredSshKeyFromMemory creates new ssh credentials using the publicKey and privateKey
+// arguments as the values for the public and private keys.
+func NewCredSshKeyFromMemory(username string, publicKey string, privateKey string, passphrase string) (int, Cred) {
+	cred := Cred{}
+	cusername := C.CString(username)
+	defer C.free(unsafe.Pointer(cusername))
+	cpublickey := C.CString(publicKey)
+	defer C.free(unsafe.Pointer(cpublickey))
+	cprivatekey := C.CString(privateKey)
+	defer C.free(unsafe.Pointer(cprivatekey))
+	cpassphrase := C.CString(passphrase)
+	defer C.free(unsafe.Pointer(cpassphrase))
+	ret := C.git_cred_ssh_key_memory_new(&cred.ptr, cusername, cpublickey, cprivatekey, cpassphrase)
+	return int(ret), cred
+}
+
 func NewCredSshKeyFromAgent(username string) (int, Cred) {
 	cred := Cred{}
 	cusername := C.CString(username)
diff --git a/describe_test.go b/describe_test.go
index 25af107..f0a45f4 100644
--- a/describe_test.go
+++ b/describe_test.go
@@ -8,6 +8,7 @@
 )
 
 func TestDescribeCommit(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/diff.go b/diff.go
index 9a7ac78..8ae0512 100644
--- a/diff.go
+++ b/diff.go
@@ -217,6 +217,33 @@
 	return int(C.git_diff_stats_files_changed(stats.ptr))
 }
 
+type DiffStatsFormat int
+
+const (
+	DiffStatsNone           DiffStatsFormat = C.GIT_DIFF_STATS_NONE
+	DiffStatsFull           DiffStatsFormat = C.GIT_DIFF_STATS_FULL
+	DiffStatsShort          DiffStatsFormat = C.GIT_DIFF_STATS_SHORT
+	DiffStatsNumber         DiffStatsFormat = C.GIT_DIFF_STATS_NUMBER
+	DiffStatsIncludeSummary DiffStatsFormat = C.GIT_DIFF_STATS_INCLUDE_SUMMARY
+)
+
+func (stats *DiffStats) String(format DiffStatsFormat,
+	width uint) (string, error) {
+	buf := C.git_buf{}
+	defer C.git_buf_free(&buf)
+
+	runtime.LockOSThread()
+	defer runtime.UnlockOSThread()
+
+	ret := C.git_diff_stats_to_buf(&buf,
+		stats.ptr, C.git_diff_stats_format_t(format), C.size_t(width))
+	if ret < 0 {
+		return "", MakeGitError(ret)
+	}
+
+	return C.GoString(buf.ptr), nil
+}
+
 func (diff *Diff) Stats() (*DiffStats, error) {
 	stats := new(DiffStats)
 
diff --git a/diff_test.go b/diff_test.go
index 850ed8e..6fbad51 100644
--- a/diff_test.go
+++ b/diff_test.go
@@ -7,6 +7,7 @@
 )
 
 func TestFindSimilar(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -61,7 +62,7 @@
 }
 
 func TestDiffTreeToTree(t *testing.T) {
-
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -189,6 +190,7 @@
 }
 
 func TestDiffBlobs(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/git_test.go b/git_test.go
index 58caf71..3385a72 100644
--- a/git_test.go
+++ b/git_test.go
@@ -58,6 +58,8 @@
 	checkFatal(t, err)
 	err = idx.AddByPath("README")
 	checkFatal(t, err)
+	err = idx.Write()
+	checkFatal(t, err)
 	treeId, err := idx.WriteTree()
 	checkFatal(t, err)
 
@@ -109,6 +111,7 @@
 }
 
 func TestOidZero(t *testing.T) {
+	t.Parallel()
 	var zeroId Oid
 
 	if !zeroId.IsZero() {
@@ -117,6 +120,7 @@
 }
 
 func TestEmptyOid(t *testing.T) {
+	t.Parallel()
 	_, err := NewOid("")
 	if err == nil || !IsErrorCode(err, ErrGeneric) {
 		t.Fatal("Should have returned invalid error")
diff --git a/index_test.go b/index_test.go
index 3a32168..f47dace 100644
--- a/index_test.go
+++ b/index_test.go
@@ -8,6 +8,7 @@
 )
 
 func TestCreateRepoAndStage(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -24,6 +25,7 @@
 }
 
 func TestIndexReadTree(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -53,6 +55,7 @@
 }
 
 func TestIndexWriteTreeTo(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -72,6 +75,7 @@
 }
 
 func TestIndexAddAndWriteTreeTo(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -146,6 +150,7 @@
 }
 
 func TestIndexAddAllNoCallback(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -167,6 +172,7 @@
 }
 
 func TestIndexAddAllCallback(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -195,6 +201,7 @@
 }
 
 func TestIndexOpen(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/merge_test.go b/merge_test.go
index 8059727..f2c84bc 100644
--- a/merge_test.go
+++ b/merge_test.go
@@ -6,6 +6,7 @@
 )
 
 func TestMergeWithSelf(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -24,6 +25,7 @@
 }
 
 func TestMergeAnalysisWithSelf(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -46,6 +48,7 @@
 }
 
 func TestMergeSameFile(t *testing.T) {
+	t.Parallel()
 	file := MergeFileInput{
 		Path:     "test",
 		Mode:     33188,
@@ -68,6 +71,7 @@
 
 }
 func TestMergeTreesWithoutAncestor(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -125,6 +129,7 @@
 }
 
 func TestMergeBase(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/note_test.go b/note_test.go
index 27e04be..9f64eb8 100644
--- a/note_test.go
+++ b/note_test.go
@@ -8,6 +8,7 @@
 )
 
 func TestCreateNote(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -27,6 +28,7 @@
 }
 
 func TestNoteIterator(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -63,6 +65,7 @@
 }
 
 func TestRemoveNote(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -86,6 +89,7 @@
 }
 
 func TestDefaultNoteRef(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/object_test.go b/object_test.go
index 2ae2a6a..cb262de 100644
--- a/object_test.go
+++ b/object_test.go
@@ -5,6 +5,7 @@
 )
 
 func TestObjectPoymorphism(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -88,6 +89,7 @@
 }
 
 func TestObjectOwner(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -104,6 +106,7 @@
 }
 
 func TestObjectPeel(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/odb_test.go b/odb_test.go
index dfd2ad0..3d22fc9 100644
--- a/odb_test.go
+++ b/odb_test.go
@@ -7,6 +7,7 @@
 )
 
 func TestOdbReadHeader(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -35,6 +36,7 @@
 }
 
 func TestOdbStream(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -64,7 +66,7 @@
 }
 
 func TestOdbHash(t *testing.T) {
-
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -92,6 +94,7 @@
 }
 
 func TestOdbForeach(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/patch_test.go b/patch_test.go
index 2d52fb4..291c705 100644
--- a/patch_test.go
+++ b/patch_test.go
@@ -6,6 +6,7 @@
 )
 
 func TestPatch(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/push_test.go b/push_test.go
index 8f6e806..f372882 100644
--- a/push_test.go
+++ b/push_test.go
@@ -5,6 +5,7 @@
 )
 
 func TestRemotePush(t *testing.T) {
+	t.Parallel()
 	repo := createBareTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/reference_test.go b/reference_test.go
index 761daf8..b6721e1 100644
--- a/reference_test.go
+++ b/reference_test.go
@@ -8,6 +8,7 @@
 )
 
 func TestRefModification(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -53,6 +54,7 @@
 }
 
 func TestReferenceIterator(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -131,6 +133,7 @@
 }
 
 func TestReferenceOwner(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -150,6 +153,7 @@
 }
 
 func TestUtil(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -177,6 +181,7 @@
 }
 
 func TestIsNote(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -210,6 +215,7 @@
 }
 
 func TestReferenceIsValidName(t *testing.T) {
+	t.Parallel()
 	if !ReferenceIsValidName("HEAD") {
 		t.Errorf("HEAD should be a valid reference name")
 	}
diff --git a/remote_test.go b/remote_test.go
index 978b803..3d00640 100644
--- a/remote_test.go
+++ b/remote_test.go
@@ -6,6 +6,7 @@
 )
 
 func TestListRemotes(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -33,6 +34,7 @@
 }
 
 func TestCertificateCheck(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -52,6 +54,7 @@
 }
 
 func TestRemoteConnect(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -63,6 +66,7 @@
 }
 
 func TestRemoteLs(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -81,6 +85,7 @@
 }
 
 func TestRemoteLsFiltering(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -107,6 +112,7 @@
 }
 
 func TestRemotePruneRefs(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -129,6 +135,7 @@
 }
 
 func TestRemotePrune(t *testing.T) {
+	t.Parallel()
 	remoteRepo := createTestRepo(t)
 	defer cleanupTestRepo(t, remoteRepo)
 
diff --git a/reset_test.go b/reset_test.go
index ec578bd..45777e4 100644
--- a/reset_test.go
+++ b/reset_test.go
@@ -6,6 +6,7 @@
 )
 
 func TestResetToCommit(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	seedTestRepo(t, repo)
 	// create commit to reset to
diff --git a/revparse_test.go b/revparse_test.go
index 75e9ffd..2835434 100644
--- a/revparse_test.go
+++ b/revparse_test.go
@@ -5,6 +5,7 @@
 )
 
 func TestRevparse(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -17,6 +18,7 @@
 }
 
 func TestRevparseSingle(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -29,6 +31,7 @@
 }
 
 func TestRevparseExt(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/status.go b/status.go
index 068a474..e68e6e9 100644
--- a/status.go
+++ b/status.go
@@ -25,6 +25,7 @@
 	StatusWtTypeChange    Status = C.GIT_STATUS_WT_TYPECHANGE
 	StatusWtRenamed       Status = C.GIT_STATUS_WT_RENAMED
 	StatusIgnored         Status = C.GIT_STATUS_IGNORED
+	StatusConflicted      Status = C.GIT_STATUS_CONFLICTED
 )
 
 type StatusEntry struct {
diff --git a/status_test.go b/status_test.go
index 5b97b00..17ed94f 100644
--- a/status_test.go
+++ b/status_test.go
@@ -7,6 +7,7 @@
 )
 
 func TestStatusFile(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -27,6 +28,7 @@
 }
 
 func TestStatusList(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/submodule_test.go b/submodule_test.go
index 43c890a..fa2e98c 100644
--- a/submodule_test.go
+++ b/submodule_test.go
@@ -5,6 +5,7 @@
 )
 
 func TestSubmoduleForeach(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/tag_test.go b/tag_test.go
index 2fdfe00..3404923 100644
--- a/tag_test.go
+++ b/tag_test.go
@@ -7,6 +7,7 @@
 )
 
 func TestCreateTag(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -26,6 +27,7 @@
 }
 
 func TestCreateTagLightweight(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -50,6 +52,7 @@
 }
 
 func TestListTags(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -79,6 +82,7 @@
 }
 
 func TestListTagsWithMatch(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -116,6 +120,7 @@
 }
 
 func TestTagForeach(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/tree_test.go b/tree_test.go
index fae395a..f5b6822 100644
--- a/tree_test.go
+++ b/tree_test.go
@@ -3,6 +3,7 @@
 import "testing"
 
 func TestTreeEntryById(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
@@ -22,6 +23,7 @@
 }
 
 func TestTreeBuilderInsert(t *testing.T) {
+	t.Parallel()
 	repo := createTestRepo(t)
 	defer cleanupTestRepo(t, repo)
 
diff --git a/walk.go b/walk.go
index 60e618d..ab1de61 100644
--- a/walk.go
+++ b/walk.go
@@ -173,10 +173,6 @@
 			return nil
 		}
 		if err != nil {
-			if err.(GitError).Code == ErrIterOver {
-				err = nil
-			}
-
 			return err
 		}
 
diff --git a/wrapper.c b/wrapper.c
index a0688c0..f4b4ecc 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -10,6 +10,12 @@
 	opts->remote_cb = (git_remote_create_cb)remoteCreateCallback;
 }
 
+void _go_git_populate_checkout_cb(git_checkout_options *opts)
+{
+	opts->notify_cb = (git_checkout_notify_cb)checkoutNotifyCallback;
+	opts->progress_cb = (git_checkout_progress_cb)checkoutProgressCallback;
+}
+
 int _go_git_visit_submodule(git_repository *repo, void *fct)
 {
 	  return git_submodule_foreach(repo, (gogit_submodule_cbk)&SubmoduleVisitor, fct);