diff --git a/index.go b/index.go index b1542d5..e4ca9d6 100644 --- a/index.go +++ b/index.go @@ -3,6 +3,11 @@ package git /* #include #include + +extern int _go_git_index_add_all(git_index*, const git_strarray*, unsigned int, void*); +extern int _go_git_index_update_all(git_index*, const git_strarray*, void*); +extern int _go_git_index_remove_all(git_index*, const git_strarray*, void*); + */ import "C" import ( @@ -12,6 +17,17 @@ import ( "unsafe" ) +type IndexMatchedPathCallback func(string, string) int + +type IndexAddOpts uint + +const ( + IndexAddDefault IndexAddOpts = C.GIT_INDEX_ADD_DEFAULT + IndexAddForce IndexAddOpts = C.GIT_INDEX_ADD_FORCE + IndexAddDisablePathspecMatch IndexAddOpts = C.GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH + IndexAddCheckPathspec IndexAddOpts = C.GIT_INDEX_ADD_CHECK_PATHSPEC +) + type Index struct { ptr *C.git_index } @@ -114,6 +130,88 @@ func (v *Index) AddByPath(path string) error { return nil } +func (v *Index) AddAll(pathspecs []string, flags IndexAddOpts, callback IndexMatchedPathCallback) error { + cpathspecs := C.git_strarray{} + cpathspecs.count = C.size_t(len(pathspecs)) + cpathspecs.strings = makeCStringsFromStrings(pathspecs) + defer freeStrarray(&cpathspecs) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + var cb *IndexMatchedPathCallback + if callback != nil { + cb = &callback + } + + ret := C._go_git_index_add_all( + v.ptr, + &cpathspecs, + C.uint(flags), + unsafe.Pointer(cb), + ) + if ret < 0 { + return MakeGitError(ret) + } + return nil +} + +func (v *Index) UpdateAll(pathspecs []string, callback IndexMatchedPathCallback) error { + cpathspecs := C.git_strarray{} + cpathspecs.count = C.size_t(len(pathspecs)) + cpathspecs.strings = makeCStringsFromStrings(pathspecs) + defer freeStrarray(&cpathspecs) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + var cb *IndexMatchedPathCallback + if callback != nil { + cb = &callback + } + + ret := C._go_git_index_update_all( + v.ptr, + &cpathspecs, + unsafe.Pointer(cb), + ) + if ret < 0 { + return MakeGitError(ret) + } + return nil +} + +func (v *Index) RemoveAll(pathspecs []string, callback IndexMatchedPathCallback) error { + cpathspecs := C.git_strarray{} + cpathspecs.count = C.size_t(len(pathspecs)) + cpathspecs.strings = makeCStringsFromStrings(pathspecs) + defer freeStrarray(&cpathspecs) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + var cb *IndexMatchedPathCallback + if callback != nil { + cb = &callback + } + + ret := C._go_git_index_remove_all( + v.ptr, + &cpathspecs, + unsafe.Pointer(cb), + ) + if ret < 0 { + return MakeGitError(ret) + } + return nil +} + +//export indexMatchedPathCallback +func indexMatchedPathCallback(cPath, cMatchedPathspec *C.char, payload unsafe.Pointer) int { + callback := (*IndexMatchedPathCallback)(payload) + return (*callback)(C.GoString(cPath), C.GoString(cMatchedPathspec)) +} + func (v *Index) RemoveByPath(path string) error { cstr := C.CString(path) defer C.free(unsafe.Pointer(cstr)) diff --git a/index_test.go b/index_test.go index cd178b9..98d9a31 100644 --- a/index_test.go +++ b/index_test.go @@ -1,6 +1,7 @@ package git import ( + "io/ioutil" "os" "runtime" "testing" @@ -54,9 +55,9 @@ func TestIndexAddAndWriteTreeTo(t *testing.T) { idx, err := NewIndex() checkFatal(t, err) - entry := IndexEntry { + entry := IndexEntry{ Path: "README", - Id: blobID, + Id: blobID, Mode: FilemodeBlob, } @@ -71,6 +72,55 @@ func TestIndexAddAndWriteTreeTo(t *testing.T) { } } +func TestIndexAddAllNoCallback(t *testing.T) { + repo := createTestRepo(t) + defer os.RemoveAll(repo.Workdir()) + + err := ioutil.WriteFile(repo.Workdir()+"/README", []byte("foo\n"), 0644) + checkFatal(t, err) + + idx, err := repo.Index() + checkFatal(t, err) + + err = idx.AddAll([]string{}, IndexAddDefault, nil) + checkFatal(t, err) + + treeId, err := idx.WriteTreeTo(repo) + checkFatal(t, err) + + if treeId.String() != "b7119b11e8ef7a1a5a34d3ac87f5b075228ac81e" { + t.Fatalf("%v", treeId.String()) + } +} + +func TestIndexAddAllCallback(t *testing.T) { + repo := createTestRepo(t) + defer os.RemoveAll(repo.Workdir()) + + err := ioutil.WriteFile(repo.Workdir()+"/README", []byte("foo\n"), 0644) + checkFatal(t, err) + + idx, err := repo.Index() + checkFatal(t, err) + + cbPath := "" + err = idx.AddAll([]string{}, IndexAddDefault, func(p, mP string) int { + cbPath = p + return 0 + }) + checkFatal(t, err) + if cbPath != "README" { + t.Fatalf("%v", cbPath) + } + + treeId, err := idx.WriteTreeTo(repo) + checkFatal(t, err) + + if treeId.String() != "b7119b11e8ef7a1a5a34d3ac87f5b075228ac81e" { + t.Fatalf("%v", treeId.String()) + } +} + func checkFatal(t *testing.T, err error) { if err == nil { return diff --git a/wrapper.c b/wrapper.c index 15e11ce..6e33fa2 100644 --- a/wrapper.c +++ b/wrapper.c @@ -104,4 +104,19 @@ int _go_git_blob_create_fromchunks(git_oid *id, return git_blob_create_fromchunks(id, repo, hintpath, _go_blob_chunk_cb, payload); } +int _go_git_index_add_all(git_index *index, const git_strarray *pathspec, unsigned int flags, void *callback) { + git_index_matched_path_cb cb = callback ? (git_index_matched_path_cb) &indexMatchedPathCallback : NULL; + return git_index_add_all(index, pathspec, flags, cb, callback); +} + +int _go_git_index_update_all(git_index *index, const git_strarray *pathspec, void *callback) { + git_index_matched_path_cb cb = callback ? (git_index_matched_path_cb) &indexMatchedPathCallback : NULL; + return git_index_update_all(index, pathspec, cb, callback); +} + +int _go_git_index_remove_all(git_index *index, const git_strarray *pathspec, void *callback) { + git_index_matched_path_cb cb = callback ? (git_index_matched_path_cb) &indexMatchedPathCallback : NULL; + return git_index_remove_all(index, pathspec, cb, callback); +} + /* EOF */