From f954871968ca6df54aab26d6984cc42bb3904ef2 Mon Sep 17 00:00:00 2001 From: Ben Navetta Date: Mon, 18 Aug 2014 22:19:06 -0400 Subject: start on status tests; fix bug in Repository.StatusList() --- status_test.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 status_test.go (limited to 'status_test.go') diff --git a/status_test.go b/status_test.go new file mode 100644 index 0000000..0cc9de3 --- /dev/null +++ b/status_test.go @@ -0,0 +1,27 @@ +package git + +import ( + "io/ioutil" + "os" + "path" + "testing" +) + +func TestEntryCount(t *testing.T) { + repo := createTestRepo(t) + defer repo.Free() + defer os.RemoveAll(repo.Workdir()) + + err := ioutil.WriteFile(path.Join(path.Dir(repo.Path()), "hello.txt"), []byte("Hello, World"), 0644) + checkFatal(t, err) + + statusList, err := repo.StatusList() + checkFatal(t, err) + + entryCount, err := statusList.EntryCount() + checkFatal(t, err) + + if entryCount != 1 { + t.Fatal("Incorrect number of status entries: ", entryCount) + } +} -- cgit v1.2.3 From a093e20a8812f2cc26fde6d4bc6ee8c21e782c39 Mon Sep 17 00:00:00 2001 From: Ben Navetta Date: Mon, 18 Aug 2014 22:58:53 -0400 Subject: add status option support --- repository.go | 20 ---------------- status.go | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ status_test.go | 2 +- 3 files changed, 76 insertions(+), 21 deletions(-) (limited to 'status_test.go') diff --git a/repository.go b/repository.go index 83e1fab..8cc966c 100644 --- a/repository.go +++ b/repository.go @@ -119,26 +119,6 @@ func (v *Repository) Index() (*Index, error) { return newIndexFromC(ptr), nil } -func (v *Repository) StatusList() (*StatusList, error) { - var ptr *C.git_status_list - options := C.git_status_options{} - - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - ret := C.git_status_init_options(&options, C.GIT_STATUS_OPTIONS_VERSION) - if ret < 0 { - return nil, MakeGitError(ret) - } - - ret = C.git_status_list_new(&ptr, v.ptr, &options) - if ret < 0 { - return nil, MakeGitError(ret) - } - - return newStatusListFromC(ptr), nil -} - func (v *Repository) lookupType(id *Oid, t ObjectType) (Object, error) { var ptr *C.git_object diff --git a/status.go b/status.go index 2baf13d..5f4b7e1 100644 --- a/status.go +++ b/status.go @@ -82,3 +82,78 @@ func (statusList *StatusList) EntryCount() (int, error) { } return int(C.git_status_list_entrycount(statusList.ptr)), nil } + +const ( + StatusOptIncludeUntracked = C.GIT_STATUS_OPT_INCLUDE_UNTRACKED + StatusOptIncludeIgnored = C.GIT_STATUS_OPT_INCLUDE_IGNORED + StatusOptIncludeUnmodified = C.GIT_STATUS_OPT_INCLUDE_UNMODIFIED + StatusOptExcludeSubmodules = C.GIT_STATUS_OPT_EXCLUDE_SUBMODULES + StatusOptRecurseUntrackedDirs = C.GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS + StatusOptDisablePathspecMatch = C.GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH + StatusOptRecurseIgnoredDirs = C.GIT_STATUS_OPT_RECURSE_IGNORED_DIRS + StatusOptRenamesHeadToIndex = C.GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX + StatusOptRenamesIndexToWorkdir = C.GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR + StatusOptSortCaseSensitively = C.GIT_STATUS_OPT_SORT_CASE_SENSITIVELY + StatusOptSortCaseInsensitively = C.GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY + StatusOptRenamesFromRewrites = C.GIT_STATUS_OPT_RENAMES_FROM_REWRITES + StatusOptNoRefresh = C.GIT_STATUS_OPT_NO_REFRESH + StatusOptUpdateIndex = C.GIT_STATUS_OPT_UPDATE_INDEX +) + +type StatusShow int + +const ( + StatusShowIndexAndWorkdir StatusShow = C.GIT_STATUS_SHOW_INDEX_AND_WORKDIR + StatusShowIndexOnly = C.GIT_STATUS_SHOW_INDEX_ONLY + StatusShowWorkdirOnly = C.GIT_STATUS_SHOW_WORKDIR_ONLY +) + +type StatusOptions struct { + Version int + Show StatusShow + Flags int + Pathspec []string +} + +func (opts *StatusOptions) toC() *C.git_status_options { + if opts == nil { + return nil + } + + cpathspec := C.git_strarray{} + if opts.Pathspec != nil { + cpathspec.count = C.size_t(len(opts.Pathspec)) + cpathspec.strings = makeCStringsFromStrings(opts.Pathspec) + defer freeStrarray(&cpathspec) + } + + copts := &C.git_status_options{ + version: C.GIT_STATUS_OPTIONS_VERSION, + show: C.git_status_show_t(opts.Show), + flags: C.uint(opts.Flags), + pathspec: cpathspec, + } + + return copts +} + +func (v *Repository) StatusList(opts *StatusOptions) (*StatusList, error) { + var ptr *C.git_status_list + var copts *C.git_status_options + + if opts != nil { + copts = opts.toC() + } else { + copts = &C.git_status_options{} + ret := C.git_status_init_options(copts, C.GIT_STATUS_OPTIONS_VERSION) + if ret < 0 { + return nil, MakeGitError(ret) + } + } + + ret := C.git_status_list_new(&ptr, v.ptr, copts) + if ret < 0 { + return nil, MakeGitError(ret) + } + return newStatusListFromC(ptr), nil +} diff --git a/status_test.go b/status_test.go index 0cc9de3..3fababe 100644 --- a/status_test.go +++ b/status_test.go @@ -15,7 +15,7 @@ func TestEntryCount(t *testing.T) { err := ioutil.WriteFile(path.Join(path.Dir(repo.Path()), "hello.txt"), []byte("Hello, World"), 0644) checkFatal(t, err) - statusList, err := repo.StatusList() + statusList, err := repo.StatusList(nil) checkFatal(t, err) entryCount, err := statusList.EntryCount() -- cgit v1.2.3 From 8fd7c2c60940300b125c40213c82b26dd38e7a78 Mon Sep 17 00:00:00 2001 From: Ben Navetta Date: Mon, 18 Aug 2014 23:12:45 -0400 Subject: add StatusFile function --- status.go | 13 ++++++++++++- status_test.go | 18 +++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) (limited to 'status_test.go') diff --git a/status.go b/status.go index 5f4b7e1..ab0469f 100644 --- a/status.go +++ b/status.go @@ -20,7 +20,7 @@ const ( StatusIndexRenamed = C.GIT_STATUS_INDEX_RENAMED StatusIndexTypeChange = C.GIT_STATUS_INDEX_TYPECHANGE StatusWtNew = C.GIT_STATUS_WT_NEW - StatusWtModified = C.GIT_STATUS_WT_NEW + StatusWtModified = C.GIT_STATUS_WT_MODIFIED StatusWtDeleted = C.GIT_STATUS_WT_DELETED StatusWtTypeChange = C.GIT_STATUS_WT_TYPECHANGE StatusWtRenamed = C.GIT_STATUS_WT_RENAMED @@ -157,3 +157,14 @@ func (v *Repository) StatusList(opts *StatusOptions) (*StatusList, error) { } return newStatusListFromC(ptr), nil } + + +func (v *Repository) StatusFile(path string) (Status, error) { + var statusFlags C.uint + cPath := C.CString(path) + ret := C.git_status_file(&statusFlags, v.ptr, cPath) + if ret < 0 { + return 0, MakeGitError(ret) + } + return Status(statusFlags), nil +} diff --git a/status_test.go b/status_test.go index 3fababe..13b778c 100644 --- a/status_test.go +++ b/status_test.go @@ -7,12 +7,28 @@ import ( "testing" ) +func TestStatusFile(t *testing.T) { + repo := createTestRepo(t) + defer repo.Free() + defer os.RemoveAll(repo.Workdir()) + + err := ioutil.WriteFile(path.Join(path.Dir(repo.Workdir()), "hello.txt"), []byte("Hello, World"), 0644) + checkFatal(t, err) + + status, err := repo.StatusFile("hello.txt") + checkFatal(t, err) + + if status != StatusWtNew { + t.Fatal("Incorrect status flags: ", status) + } +} + func TestEntryCount(t *testing.T) { repo := createTestRepo(t) defer repo.Free() defer os.RemoveAll(repo.Workdir()) - err := ioutil.WriteFile(path.Join(path.Dir(repo.Path()), "hello.txt"), []byte("Hello, World"), 0644) + err := ioutil.WriteFile(path.Join(path.Dir(repo.Workdir()), "hello.txt"), []byte("Hello, World"), 0644) checkFatal(t, err) statusList, err := repo.StatusList(nil) -- cgit v1.2.3 From fe1e6b83edfa8456f6ed8eb83eaa6fe57771e875 Mon Sep 17 00:00:00 2001 From: Ben Navetta Date: Tue, 19 Aug 2014 08:08:46 -0400 Subject: comment out issue with entry count --- status_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'status_test.go') diff --git a/status_test.go b/status_test.go index 13b778c..228ee0e 100644 --- a/status_test.go +++ b/status_test.go @@ -38,6 +38,7 @@ func TestEntryCount(t *testing.T) { checkFatal(t, err) if entryCount != 1 { - t.Fatal("Incorrect number of status entries: ", entryCount) + // FIXME: this is 0 even though the same setup above returns the correct status, as does a call to StatusFile here + // t.Fatal("Incorrect number of status entries: ", entryCount) } } -- cgit v1.2.3 From 1cb654e4f2ae536f71773dbe0bd808874b832d9c Mon Sep 17 00:00:00 2001 From: Ben Navetta Date: Tue, 19 Aug 2014 08:51:18 -0400 Subject: add git_status_foreach binding --- status.go | 26 ++++++++++++++++++++++++++ status_test.go | 23 +++++++++++++++++++++++ wrapper.c | 7 ++++++- 3 files changed, 55 insertions(+), 1 deletion(-) (limited to 'status_test.go') diff --git a/status.go b/status.go index ab0469f..4523cb8 100644 --- a/status.go +++ b/status.go @@ -3,11 +3,14 @@ package git /* #include #include + +int _go_git_status_foreach(git_repository *repo, void *data); */ import "C" import ( "runtime" + "unsafe" ) type Status int @@ -168,3 +171,26 @@ func (v *Repository) StatusFile(path string) (Status, error) { } return Status(statusFlags), nil } + +type StatusCallback func(path string, status Status) int + +//export fileStatusForeach +func fileStatusForeach(_path *C.char, _flags C.uint, _payload unsafe.Pointer) C.int { + path := C.GoString(_path) + flags := Status(_flags) + + cb := (*StatusCallback)(_payload) + return C.int((*cb)(path, flags)) +} + +func (v *Repository) StatusForeach(callback StatusCallback) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C._go_git_status_foreach(v.ptr, unsafe.Pointer(&callback)) + + if ret < 0 { + return MakeGitError(ret) + } + return nil +} diff --git a/status_test.go b/status_test.go index 228ee0e..a0ff1d3 100644 --- a/status_test.go +++ b/status_test.go @@ -23,6 +23,29 @@ func TestStatusFile(t *testing.T) { } } +func TestStatusForeach(t *testing.T) { + repo := createTestRepo(t) + defer repo.Free() + defer os.RemoveAll(repo.Workdir()) + + err := ioutil.WriteFile(path.Join(path.Dir(repo.Workdir()), "hello.txt"), []byte("Hello, World"), 0644) + checkFatal(t, err) + + statusFound := false + err = repo.StatusForeach(func (path string, statusFlags Status) int { + if path == "hello.txt" && statusFlags & StatusWtNew != 0 { + statusFound = true + } + + return 0 + }); + checkFatal(t, err) + + if !statusFound { + t.Fatal("Status callback not called with the new file") + } +} + func TestEntryCount(t *testing.T) { repo := createTestRepo(t) defer repo.Free() diff --git a/wrapper.c b/wrapper.c index 2fd8fb7..09dba46 100644 --- a/wrapper.c +++ b/wrapper.c @@ -45,7 +45,7 @@ void _go_git_refdb_backend_free(git_refdb_backend *backend) int _go_git_diff_foreach(git_diff *diff, int eachFile, int eachHunk, int eachLine, void *payload) { - git_diff_file_cb fcb = NULL; + git_diff_file_cb fcb = NULL; git_diff_hunk_cb hcb = NULL; git_diff_line_cb lcb = NULL; @@ -105,4 +105,9 @@ 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_status_foreach(git_repository *repo, void *data) +{ + return git_status_foreach(repo, (git_status_cb)fileStatusForeach, data); +} + /* EOF */ -- cgit v1.2.3 From 33ae83f4d9b78501549fc880c1e2dd055466808c Mon Sep 17 00:00:00 2001 From: Ben Navetta Date: Mon, 25 Aug 2014 18:15:36 -0400 Subject: remove status_foreach binding --- status.go | 26 -------------------------- status_test.go | 23 ----------------------- wrapper.c | 5 ----- 3 files changed, 54 deletions(-) (limited to 'status_test.go') diff --git a/status.go b/status.go index efe6eb0..644b13e 100644 --- a/status.go +++ b/status.go @@ -3,14 +3,11 @@ package git /* #include #include - -int _go_git_status_foreach(git_repository *repo, void *data); */ import "C" import ( "runtime" - "unsafe" ) type Status int @@ -170,26 +167,3 @@ func (v *Repository) StatusFile(path string) (Status, error) { } return Status(statusFlags), nil } - -type StatusCallback func(path string, status Status) int - -//export fileStatusForeach -func fileStatusForeach(_path *C.char, _flags C.uint, _payload unsafe.Pointer) C.int { - path := C.GoString(_path) - flags := Status(_flags) - - cb := (*StatusCallback)(_payload) - return C.int((*cb)(path, flags)) -} - -func (v *Repository) StatusForeach(callback StatusCallback) error { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - ret := C._go_git_status_foreach(v.ptr, unsafe.Pointer(&callback)) - - if ret < 0 { - return MakeGitError(ret) - } - return nil -} diff --git a/status_test.go b/status_test.go index a0ff1d3..228ee0e 100644 --- a/status_test.go +++ b/status_test.go @@ -23,29 +23,6 @@ func TestStatusFile(t *testing.T) { } } -func TestStatusForeach(t *testing.T) { - repo := createTestRepo(t) - defer repo.Free() - defer os.RemoveAll(repo.Workdir()) - - err := ioutil.WriteFile(path.Join(path.Dir(repo.Workdir()), "hello.txt"), []byte("Hello, World"), 0644) - checkFatal(t, err) - - statusFound := false - err = repo.StatusForeach(func (path string, statusFlags Status) int { - if path == "hello.txt" && statusFlags & StatusWtNew != 0 { - statusFound = true - } - - return 0 - }); - checkFatal(t, err) - - if !statusFound { - t.Fatal("Status callback not called with the new file") - } -} - func TestEntryCount(t *testing.T) { repo := createTestRepo(t) defer repo.Free() diff --git a/wrapper.c b/wrapper.c index 09dba46..45c4358 100644 --- a/wrapper.c +++ b/wrapper.c @@ -105,9 +105,4 @@ 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_status_foreach(git_repository *repo, void *data) -{ - return git_status_foreach(repo, (git_status_cb)fileStatusForeach, data); -} - /* EOF */ -- cgit v1.2.3 From 80997c6fa55da6a25c30dccab379e808d9f07b28 Mon Sep 17 00:00:00 2001 From: Ben Navetta Date: Mon, 25 Aug 2014 23:18:00 -0400 Subject: fix status list to handle null head_to_index in entries --- status.go | 16 ++++++++++++++-- status_test.go | 22 ++++++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) (limited to 'status_test.go') diff --git a/status.go b/status.go index f69cd14..09a06c4 100644 --- a/status.go +++ b/status.go @@ -35,10 +35,21 @@ type StatusEntry struct { } func statusEntryFromC(statusEntry *C.git_status_entry) StatusEntry { + var headToIndex DiffDelta = DiffDelta{} + var indexToWorkdir DiffDelta = DiffDelta{} + + // Based on the libgit2 status example, head_to_index can be null in some cases + if statusEntry.head_to_index != nil { + headToIndex = diffDeltaFromC(statusEntry.head_to_index) + } + if statusEntry.index_to_workdir != nil { + indexToWorkdir = diffDeltaFromC(statusEntry.index_to_workdir) + } + return StatusEntry { Status: Status(statusEntry.status), - HeadToIndex: diffDeltaFromC(statusEntry.head_to_index), - IndexToWorkdir: diffDeltaFromC(statusEntry.index_to_workdir), + HeadToIndex: headToIndex, + IndexToWorkdir: indexToWorkdir, } } @@ -158,6 +169,7 @@ func (v *Repository) StatusList(opts *StatusOptions) (*StatusList, error) { if ret < 0 { return nil, MakeGitError(ret) } + return newStatusListFromC(ptr), nil } diff --git a/status_test.go b/status_test.go index 228ee0e..4be4824 100644 --- a/status_test.go +++ b/status_test.go @@ -23,22 +23,36 @@ func TestStatusFile(t *testing.T) { } } -func TestEntryCount(t *testing.T) { +func TestStatusList(t *testing.T) { repo := createTestRepo(t) + // This commits the test repo README, so it doesn't show up in the status list and there's a head to compare to + seedTestRepo(t, repo) defer repo.Free() defer os.RemoveAll(repo.Workdir()) err := ioutil.WriteFile(path.Join(path.Dir(repo.Workdir()), "hello.txt"), []byte("Hello, World"), 0644) checkFatal(t, err) - statusList, err := repo.StatusList(nil) + opts := &StatusOptions{} + opts.Show = StatusShowIndexAndWorkdir + opts.Flags = StatusOptIncludeUntracked | StatusOptRenamesHeadToIndex | StatusOptSortCaseSensitively + + statusList, err := repo.StatusList(opts) checkFatal(t, err) entryCount, err := statusList.EntryCount() checkFatal(t, err) if entryCount != 1 { - // FIXME: this is 0 even though the same setup above returns the correct status, as does a call to StatusFile here - // t.Fatal("Incorrect number of status entries: ", entryCount) + t.Fatal("Incorrect number of status entries: ", entryCount) + } + + entry, err := statusList.ByIndex(0) + checkFatal(t, err) + if entry.Status != StatusWtNew { + t.Fatal("Incorrect status flags: ", entry.Status) + } + if entry.IndexToWorkdir.NewFile.Path != "hello.txt" { + t.Fatal("Incorrect entry path: ", entry.IndexToWorkdir.NewFile.Path) } } -- cgit v1.2.3