From d3bd8903f8310baf5395d63aec1e3d517578156d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Mon, 7 Mar 2016 11:33:44 +0100 Subject: [PATCH 01/13] Update libgit2 version to install on Travis to 24 --- script/install-libgit2.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/script/install-libgit2.sh b/script/install-libgit2.sh index 9bf6b37..f2468c8 100755 --- a/script/install-libgit2.sh +++ b/script/install-libgit2.sh @@ -13,9 +13,10 @@ if [ "x$TRAVIS_BRANCH" = "xnext" ]; then fi cd "${HOME}" -wget -O libgit2-0.23.1.tar.gz https://github.com/libgit2/libgit2/archive/v0.23.1.tar.gz -tar -xzvf libgit2-0.23.1.tar.gz -cd libgit2-0.23.1 && mkdir build && cd build +LG2VER="0.24.0" +wget -O libgit2-${LG2VER}.tar.gz https://github.com/libgit2/libgit2/archive/v${LG2VER}.tar.gz +tar -xzvf libgit2-${LG2VER}.tar.gz +cd libgit2-${LG2VER} && mkdir build && cd build cmake -DTHREADSAFE=ON -DBUILD_CLAR=OFF -DCMAKE_BUILD_TYPE="RelWithDebInfo" .. && make && sudo make install sudo ldconfig cd "${TRAVIS_BUILD_DIR}" From 975228d55c7c4875374bf79e022afb8fa725d660 Mon Sep 17 00:00:00 2001 From: Hiroshi Ioka Date: Sun, 6 Mar 2016 12:18:32 +0900 Subject: [PATCH 02/13] add DiffTreeToIndex This is equivalent to `git diff --cached Date: Wed, 27 Apr 2016 14:53:21 +0200 Subject: [PATCH 03/13] Error out if we detect an incompatible libgit2 version The master version supports only v0.24 so let's enforce that via the compiler. --- git.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/git.go b/git.go index 45b01d5..ed891e6 100644 --- a/git.go +++ b/git.go @@ -4,6 +4,11 @@ package git #include #include #cgo pkg-config: libgit2 + +#if LIBGIT2_VER_MAJOR != 0 || LIBGIT2_VER_MINOR != 24 +# error "Invalid libgit2 version; this git2go supports libgit2 v0.24" +#endif + */ import "C" import ( From 8919236801226cf64fc42ccdaf420e00d590317a Mon Sep 17 00:00:00 2001 From: Mirko Nosenzo Date: Sun, 29 May 2016 14:49:00 +0200 Subject: [PATCH 04/13] ResetDefaultToCommit maps git_reset_default Added support for default reset behavior --- reset.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/reset.go b/reset.go index 9da7625..031f5bd 100644 --- a/reset.go +++ b/reset.go @@ -24,3 +24,19 @@ func (r *Repository) ResetToCommit(commit *Commit, resetType ResetType, opts *Ch } return nil } + +func (r *Repository) ResetDefaultToCommit(commit *Commit, pathspecs []string) error { + cpathspecs := C.git_strarray{} + cpathspecs.count = C.size_t(len(pathspecs)) + cpathspecs.strings = makeCStringsFromStrings(pathspecs) + defer freeStrarray(&cpathspecs) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_reset_default(r.ptr, commit.ptr, &cpathspecs) + + if ret < 0 { + return MakeGitError(ret) + } + return nil +} From 8b855ce7650de8aabb9d23c4cbfef9467c4d4f77 Mon Sep 17 00:00:00 2001 From: Mirko Nosenzo Date: Sun, 29 May 2016 14:46:55 +0200 Subject: [PATCH 05/13] Tag Remove Added support for removal of a Tag --- repository.go | 2 +- tag.go | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/repository.go b/repository.go index 77e9f9c..efc506e 100644 --- a/repository.go +++ b/repository.go @@ -28,7 +28,7 @@ type Repository struct { // read, write and delete notes from this repository. Notes NoteCollection // Tags represents the collection of tags and can be used to create, - // list and iterate tags in this repository. + // list, iterate and remove tags in this repository. Tags TagsCollection } diff --git a/tag.go b/tag.go index 8957430..81d7258 100644 --- a/tag.go +++ b/tag.go @@ -83,6 +83,21 @@ func (c *TagsCollection) Create( return oid, nil } +func (c *TagsCollection) Remove(name string) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + ret := C.git_tag_delete(c.repo.ptr, cname) + if ret < 0 { + return MakeGitError(ret) + } + + return nil +} + // CreateLightweight creates a new lightweight tag pointing to a commit // and returns the id of the target object. // From 298f2e2111905388e3d10cd0db0221a22dc7a62f Mon Sep 17 00:00:00 2001 From: Mirko Nosenzo Date: Sun, 29 May 2016 13:13:58 +0200 Subject: [PATCH 06/13] BranchAll maps GIT_BRANCH_ALL Added support to All Branch Iteration and Lookup --- branch.go | 1 + 1 file changed, 1 insertion(+) diff --git a/branch.go b/branch.go index df72dba..a869054 100644 --- a/branch.go +++ b/branch.go @@ -13,6 +13,7 @@ import ( type BranchType uint const ( + BranchAll BranchType = C.GIT_BRANCH_ALL BranchLocal BranchType = C.GIT_BRANCH_LOCAL BranchRemote BranchType = C.GIT_BRANCH_REMOTE ) From 82f86f2f13213cfadfafc07a033c269095386dbc Mon Sep 17 00:00:00 2001 From: Mirko Nosenzo Date: Sun, 29 May 2016 14:37:37 +0200 Subject: [PATCH 07/13] StatusConflicted maps GIT_STATUS_CONFLICTED Added support for file in conflicted status --- status.go | 1 + 1 file changed, 1 insertion(+) diff --git a/status.go b/status.go index 068a474..e68e6e9 100644 --- a/status.go +++ b/status.go @@ -25,6 +25,7 @@ const ( 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 { From 981538924c7607980dd8328564cad6c0aedd6154 Mon Sep 17 00:00:00 2001 From: Travis Lane Date: Thu, 7 Apr 2016 21:51:00 -0700 Subject: [PATCH 08/13] diff: Add DiffStats String This implements git_diff_stats_to_buf which provides the output for git diff --stats. --- diff.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/diff.go b/diff.go index 9a7ac78..8ae0512 100644 --- a/diff.go +++ b/diff.go @@ -217,6 +217,33 @@ func (stats *DiffStats) FilesChanged() int { 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) From e55c00eca7e70e2d02860cda3cdc9169a88ece36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sat, 27 Aug 2016 19:21:05 +0200 Subject: [PATCH 09/13] Run the tests in parallel This saves about 1s, or 1/3 of the test runtime. The linking is still much slower, but this we can control. --- blame_test.go | 1 + blob_test.go | 1 + branch_test.go | 2 ++ cherrypick_test.go | 1 + clone_test.go | 2 ++ config_test.go | 1 + describe_test.go | 1 + diff_test.go | 4 +++- git_test.go | 2 ++ index_test.go | 7 +++++++ merge_test.go | 5 +++++ note_test.go | 4 ++++ object_test.go | 3 +++ odb_test.go | 5 ++++- patch_test.go | 1 + push_test.go | 1 + reference_test.go | 6 ++++++ remote_test.go | 7 +++++++ reset_test.go | 1 + revparse_test.go | 3 +++ status_test.go | 2 ++ submodule_test.go | 1 + tag_test.go | 5 +++++ tree_test.go | 2 ++ 24 files changed, 66 insertions(+), 2 deletions(-) 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 @@ import ( ) func TestBlame(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) diff --git a/blob_test.go b/blob_test.go index 2b5ec4f..719d185 100644 --- a/blob_test.go +++ b/blob_test.go @@ -5,6 +5,7 @@ import ( ) func TestCreateBlobFromBuffer(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) 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 @@ import ( ) func TestBranchIterator(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -27,6 +28,7 @@ func TestBranchIterator(t *testing.T) { } func TestBranchIteratorEach(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) 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 readReadme(t *testing.T, repo *Repository) string { } func TestCherrypick(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) 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 @@ const ( ) func TestClone(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -35,6 +36,7 @@ func TestClone(t *testing.T) { } 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 @@ var tests = []TestRunner{ } func TestConfigLookups(t *testing.T) { + t.Parallel() var ( err error c *Config 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 @@ import ( ) func TestDescribeCommit(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) 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 @@ import ( ) func TestFindSimilar(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -61,7 +62,7 @@ func TestFindSimilar(t *testing.T) { } func TestDiffTreeToTree(t *testing.T) { - + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -189,6 +190,7 @@ func createTestTrees(t *testing.T, repo *Repository) (originalTree *Tree, newTre } 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..bdb6837 100644 --- a/git_test.go +++ b/git_test.go @@ -109,6 +109,7 @@ func updateReadme(t *testing.T, repo *Repository, content string) (*Oid, *Oid) { } func TestOidZero(t *testing.T) { + t.Parallel() var zeroId Oid if !zeroId.IsZero() { @@ -117,6 +118,7 @@ func TestOidZero(t *testing.T) { } 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 5f6b375..600b8b1 100644 --- a/index_test.go +++ b/index_test.go @@ -8,6 +8,7 @@ import ( ) func TestCreateRepoAndStage(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -24,6 +25,7 @@ func TestCreateRepoAndStage(t *testing.T) { } func TestIndexReadTree(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -53,6 +55,7 @@ func TestIndexReadTree(t *testing.T) { } func TestIndexWriteTreeTo(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -72,6 +75,7 @@ func TestIndexWriteTreeTo(t *testing.T) { } func TestIndexAddAndWriteTreeTo(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -106,6 +110,7 @@ func TestIndexAddAndWriteTreeTo(t *testing.T) { } func TestIndexAddAllNoCallback(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -127,6 +132,7 @@ func TestIndexAddAllNoCallback(t *testing.T) { } func TestIndexAddAllCallback(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -155,6 +161,7 @@ func TestIndexAddAllCallback(t *testing.T) { } 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 @@ import ( ) func TestMergeWithSelf(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -24,6 +25,7 @@ func TestMergeWithSelf(t *testing.T) { } func TestMergeAnalysisWithSelf(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -46,6 +48,7 @@ func TestMergeAnalysisWithSelf(t *testing.T) { } func TestMergeSameFile(t *testing.T) { + t.Parallel() file := MergeFileInput{ Path: "test", Mode: 33188, @@ -68,6 +71,7 @@ func TestMergeSameFile(t *testing.T) { } func TestMergeTreesWithoutAncestor(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -125,6 +129,7 @@ func appendCommit(t *testing.T, repo *Repository) (*Oid, *Oid) { } 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 @@ import ( ) func TestCreateNote(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -27,6 +28,7 @@ func TestCreateNote(t *testing.T) { } func TestNoteIterator(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -63,6 +65,7 @@ func TestNoteIterator(t *testing.T) { } func TestRemoveNote(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -86,6 +89,7 @@ func TestRemoveNote(t *testing.T) { } 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 @@ import ( ) func TestObjectPoymorphism(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -88,6 +89,7 @@ func checkOwner(t *testing.T, repo *Repository, obj Object) { } func TestObjectOwner(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -104,6 +106,7 @@ func TestObjectOwner(t *testing.T) { } 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 @@ import ( ) func TestOdbReadHeader(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -35,6 +36,7 @@ func TestOdbReadHeader(t *testing.T) { } func TestOdbStream(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -64,7 +66,7 @@ func TestOdbStream(t *testing.T) { } func TestOdbHash(t *testing.T) { - + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -92,6 +94,7 @@ Initial commit.` } 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 @@ import ( ) 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 @@ import ( ) 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 @@ import ( ) func TestRefModification(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -53,6 +54,7 @@ func TestRefModification(t *testing.T) { } func TestReferenceIterator(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -131,6 +133,7 @@ func TestReferenceIterator(t *testing.T) { } func TestReferenceOwner(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -150,6 +153,7 @@ func TestReferenceOwner(t *testing.T) { } func TestUtil(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -177,6 +181,7 @@ func TestUtil(t *testing.T) { } func TestIsNote(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -210,6 +215,7 @@ func TestIsNote(t *testing.T) { } 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 @@ import ( ) func TestListRemotes(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -33,6 +34,7 @@ func assertHostname(cert *Certificate, valid bool, hostname string, t *testing.T } func TestCertificateCheck(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -52,6 +54,7 @@ func TestCertificateCheck(t *testing.T) { } func TestRemoteConnect(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -63,6 +66,7 @@ func TestRemoteConnect(t *testing.T) { } func TestRemoteLs(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -81,6 +85,7 @@ func TestRemoteLs(t *testing.T) { } func TestRemoteLsFiltering(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -107,6 +112,7 @@ func TestRemoteLsFiltering(t *testing.T) { } func TestRemotePruneRefs(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -129,6 +135,7 @@ func TestRemotePruneRefs(t *testing.T) { } 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 @@ import ( ) 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 @@ import ( ) func TestRevparse(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -17,6 +18,7 @@ func TestRevparse(t *testing.T) { } func TestRevparseSingle(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -29,6 +31,7 @@ func TestRevparseSingle(t *testing.T) { } func TestRevparseExt(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) 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 @@ import ( ) func TestStatusFile(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -27,6 +28,7 @@ func TestStatusFile(t *testing.T) { } 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 @@ import ( ) 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 @@ import ( ) func TestCreateTag(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -26,6 +27,7 @@ func TestCreateTag(t *testing.T) { } func TestCreateTagLightweight(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -50,6 +52,7 @@ func TestCreateTagLightweight(t *testing.T) { } func TestListTags(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -79,6 +82,7 @@ func TestListTags(t *testing.T) { } func TestListTagsWithMatch(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -116,6 +120,7 @@ func TestListTagsWithMatch(t *testing.T) { } 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 @@ package git import "testing" func TestTreeEntryById(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -22,6 +23,7 @@ func TestTreeEntryById(t *testing.T) { } func TestTreeBuilderInsert(t *testing.T) { + t.Parallel() repo := createTestRepo(t) defer cleanupTestRepo(t, repo) From 3c1ba8c40e4d654bfca8b535c861a63c41b16f27 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Sat, 27 Aug 2016 20:44:46 +0200 Subject: [PATCH 10/13] Add test for slice-to-slice and GCo pointer detection --- .travis.yml | 1 + blob_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/.travis.yml b/.travis.yml index f796389..016cf2d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,7 @@ go: - 1.3 - 1.4 - 1.5 + - 1.6 - tip matrix: diff --git a/blob_test.go b/blob_test.go index 2b5ec4f..652c50c 100644 --- a/blob_test.go +++ b/blob_test.go @@ -1,9 +1,21 @@ 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) { repo := createTestRepo(t) defer cleanupTestRepo(t, repo) @@ -14,4 +26,18 @@ func TestCreateBlobFromBuffer(t *testing.T) { if id.String() != "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391" { t.Fatal("Empty buffer did not deliver empty blob id") } + + for _, data := range []([]byte){[]byte("hello there"), doublePointerBytes()} { + expected := make([]byte, len(data)) + copy(expected, data) + id, err = repo.CreateBlobFromBuffer(data) + checkFatal(t, err) + + blob, err := repo.LookupBlob(id) + checkFatal(t, err) + if !bytes.Equal(blob.Contents(), expected) { + t.Fatal("Loaded bytes don't match original bytes:", + blob.Contents(), "!=", expected) + } + } } From b5d213c2c1229ea5de524ee24a9d9635a9cf303f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sat, 27 Aug 2016 20:47:41 +0200 Subject: [PATCH 11/13] Remove unecessary copy --- blob_test.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/blob_test.go b/blob_test.go index 652c50c..6b7cd49 100644 --- a/blob_test.go +++ b/blob_test.go @@ -28,16 +28,14 @@ func TestCreateBlobFromBuffer(t *testing.T) { } for _, data := range []([]byte){[]byte("hello there"), doublePointerBytes()} { - expected := make([]byte, len(data)) - copy(expected, data) id, err = repo.CreateBlobFromBuffer(data) checkFatal(t, err) blob, err := repo.LookupBlob(id) checkFatal(t, err) - if !bytes.Equal(blob.Contents(), expected) { + if !bytes.Equal(blob.Contents(), data) { t.Fatal("Loaded bytes don't match original bytes:", - blob.Contents(), "!=", expected) + blob.Contents(), "!=", data) } } } From b41e4c4ac7c7ec4d45ec5d8903077bd01264549f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sat, 27 Aug 2016 20:51:13 +0200 Subject: [PATCH 12/13] Work around Go 1.6's CGo pointer check It depends heavily on the expression at the call site an whether it can figure out whether we're using a slice or not, so provid an incantation that does this. --- blob.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/blob.go b/blob.go index 1a86e60..8b3e94f 100644 --- a/blob.go +++ b/blob.go @@ -37,15 +37,24 @@ func (repo *Repository) CreateBlobFromBuffer(data []byte) (*Oid, error) { 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) } From 5c678353faa4f180ee4ad8a5e58ca71e093cf757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sat, 27 Aug 2016 20:52:07 +0200 Subject: [PATCH 13/13] Add Go 1.7 to the build list --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 016cf2d..79ad168 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ go: - 1.4 - 1.5 - 1.6 + - 1.7 - tip matrix: