From 1b44c0a2343cc87cb32513ef4625c590c8ecbe8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 15 Mar 2015 01:21:21 +0100 Subject: [PATCH 01/11] Add a bit more on next vs master --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 51543a8..386ff83 100644 --- a/README.md +++ b/README.md @@ -8,17 +8,23 @@ Go bindings for [libgit2](http://libgit2.github.com/). The `master` branch follo Installing ---------- -This project needs libgit2, which is written in C so we need to build that as well. In order to build libgit2, 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. +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 manger 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. ### Stable version -git2go has versioned branches which indicate which version of libgit2 they work against. Install the development package it on your system via your favourite package manager or from source and you can use a service like gopkg.in to use the appropriate version. For the libgit2 v0.22 case, you can use +git2go has `master` which tracks the latest release of libgit2, and versioned branches which indicate which version of libgit2 they work against. Install the development package it on your system via your favourite package manager or from source and you can use a service like gopkg.in to use the appropriate version. For the libgit2 v0.22 case, you can use import "gopkg.in/libgit2/git2go.v22" -to use a version of git2go which will work against libgit2 v0.22 and dynamically link to the library. +to use a version of git2go which will work against libgit2 v0.22 and dynamically link to the library. You can use -### From master + import "github.com/libgit2/git2go" + +to use the version which works against the latest release. + +### From `next` The `next` branch follows libgit2's master branch, which means there is no stable API or ABI to link against. git2go can statically link against a vendored version of libgit2. From c4b8861b34ead7b06986ea5711c2d9528628215f Mon Sep 17 00:00:00 2001 From: Geoffrey Ragot Date: Sat, 14 Mar 2015 15:27:47 +0100 Subject: [PATCH 02/11] Add possibiliy of checkout on specific path --- checkout.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/checkout.go b/checkout.go index 06d010c..c507172 100644 --- a/checkout.go +++ b/checkout.go @@ -38,6 +38,7 @@ type CheckoutOpts struct { 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 } func (opts *CheckoutOpts) toC() *C.git_checkout_options { @@ -65,6 +66,11 @@ func populateCheckoutOpts(ptr *C.git_checkout_options, opts *CheckoutOpts) *C.gi if opts.TargetDirectory != "" { ptr.target_directory = C.CString(opts.TargetDirectory) } + if len(opts.Paths) > 0 { + ptr.paths.strings = makeCStringsFromStrings(opts.Paths) + ptr.paths.count = C.size_t(len(opts.Paths)) + } + return ptr } @@ -73,6 +79,9 @@ func freeCheckoutOpts(ptr *C.git_checkout_options) { return } C.free(unsafe.Pointer(ptr.target_directory)) + if ptr.paths.count > 0 { + freeStrarray(&ptr.paths) + } } // Updates files in the index and the working tree to match the content of @@ -128,4 +137,4 @@ func (v *Repository) CheckoutTree(tree *Tree, opts *CheckoutOpts) error { } return nil -} +} \ No newline at end of file From 43102043fb5311939e9ec50f7210ffb51183684a Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Wed, 11 Mar 2015 16:10:32 -0700 Subject: [PATCH 03/11] Add Commit.Amend --- commit.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/commit.go b/commit.go index 57e1a77..52f7c01 100644 --- a/commit.go +++ b/commit.go @@ -9,6 +9,7 @@ import "C" import ( "runtime" + "unsafe" ) // Commit @@ -70,3 +71,40 @@ func (c *Commit) ParentId(n uint) *Oid { func (c *Commit) ParentCount() uint { return uint(C.git_commit_parentcount(c.cast_ptr)) } + +func (c *Commit) Amend(refname string, author, committer *Signature, message string, tree *Tree) (*Oid, error) { + var cref *C.char + if refname == "" { + cref = nil + } else { + cref = C.CString(refname) + defer C.free(unsafe.Pointer(cref)) + } + + cmsg := C.CString(message) + defer C.free(unsafe.Pointer(cmsg)) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + authorSig, err := author.toC() + if err != nil { + return nil, err + } + defer C.git_signature_free(authorSig) + + committerSig, err := committer.toC() + if err != nil { + return nil, err + } + defer C.git_signature_free(committerSig) + + oid := new(Oid) + + cerr := C.git_commit_amend(oid.toC(), c.cast_ptr, cref, authorSig, committerSig, nil, cmsg, tree.cast_ptr) + if cerr < 0 { + return nil, MakeGitError(cerr) + } + + return oid, nil +} From 8622831b1128fee96da8a1829b948a49adc3dd6e Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Wed, 11 Mar 2015 16:12:22 -0700 Subject: [PATCH 04/11] Add DiffTreeToWorkdirWithIndex --- diff.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/diff.go b/diff.go index 63fa867..54e4a92 100644 --- a/diff.go +++ b/diff.go @@ -595,3 +595,28 @@ func (v *Repository) DiffTreeToWorkdir(oldTree *Tree, opts *DiffOptions) (*Diff, } return newDiffFromC(diffPtr), nil } + +func (v *Repository) DiffTreeToWorkdirWithIndex(oldTree *Tree, opts *DiffOptions) (*Diff, error) { + var diffPtr *C.git_diff + var oldPtr *C.git_tree + + if oldTree != nil { + oldPtr = oldTree.cast_ptr + } + + copts, notifyData := diffOptionsToC(opts) + defer freeDiffOptions(copts) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ecode := C.git_diff_tree_to_workdir_with_index(&diffPtr, v.ptr, oldPtr, copts) + if ecode < 0 { + return nil, MakeGitError(ecode) + } + + if notifyData != nil && notifyData.Diff != nil { + return notifyData.Diff, nil + } + return newDiffFromC(diffPtr), nil +} From 524cc7967be53176108e5c703818ccdd18882100 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Wed, 11 Mar 2015 16:12:39 -0700 Subject: [PATCH 05/11] Add DiffIndexToWorkdir --- diff.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/diff.go b/diff.go index 54e4a92..23469f2 100644 --- a/diff.go +++ b/diff.go @@ -620,3 +620,28 @@ func (v *Repository) DiffTreeToWorkdirWithIndex(oldTree *Tree, opts *DiffOptions } return newDiffFromC(diffPtr), nil } + +func (v *Repository) DiffIndexToWorkdir(index *Index, opts *DiffOptions) (*Diff, error) { + var diffPtr *C.git_diff + var indexPtr *C.git_index + + if index != nil { + indexPtr = index.ptr + } + + copts, notifyData := diffOptionsToC(opts) + defer freeDiffOptions(copts) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ecode := C.git_diff_index_to_workdir(&diffPtr, v.ptr, indexPtr, copts) + if ecode < 0 { + return nil, MakeGitError(ecode) + } + + if notifyData != nil && notifyData.Diff != nil { + return notifyData.Diff, nil + } + return newDiffFromC(diffPtr), nil +} From b3e7304abf6f0c4ef50e973acb220c40a5ddac86 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 23 Mar 2015 12:02:08 -0700 Subject: [PATCH 06/11] Add a FIXME. --- index.go | 1 + 1 file changed, 1 insertion(+) diff --git a/index.go b/index.go index 6b90758..9f37f33 100644 --- a/index.go +++ b/index.go @@ -287,6 +287,7 @@ func (v *Index) HasConflicts() bool { return C.git_index_has_conflicts(v.ptr) != 0 } +// FIXME: this might return an error func (v *Index) CleanupConflicts() { C.git_index_conflict_cleanup(v.ptr) } From 6454808f693435983456bf98a40478641d211c7f Mon Sep 17 00:00:00 2001 From: Artiom Di Date: Fri, 3 Apr 2015 14:53:15 +0300 Subject: [PATCH 07/11] Test on travis using Go1.4 too --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index e833a32..f8b7e93 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ go: - 1.1 - 1.2 - 1.3 + - 1.4 - tip matrix: From e300945a3d456af1b619447347cd19a779b7a8f5 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 24 Apr 2015 12:59:29 +0200 Subject: [PATCH 08/11] tests: always clean up temporary repository dirs Some test repositories are not correctly removed after the tests did run. Fix by introducing a function that is to be used for cleaning up temporary test repositories. --- blame_test.go | 4 +--- blob_test.go | 3 +-- branch_test.go | 8 +++++++- cherrypick_test.go | 2 ++ clone_test.go | 7 +++---- diff_test.go | 7 ++----- git_test.go | 13 +++++++++++++ index_test.go | 13 ++++++------- merge_test.go | 11 +++++------ note_test.go | 10 +++++----- object_test.go | 7 ++++--- odb_test.go | 10 ++++++---- patch_test.go | 3 +-- push_test.go | 6 +++--- reference_test.go | 10 +++++----- remote_test.go | 28 +++++++++------------------- revparse_test.go | 7 +++---- status_test.go | 8 +++----- submodule_test.go | 2 ++ tag_test.go | 4 ++-- 20 files changed, 83 insertions(+), 80 deletions(-) diff --git a/blame_test.go b/blame_test.go index 1785042..a2a4d38 100644 --- a/blame_test.go +++ b/blame_test.go @@ -1,15 +1,13 @@ package git import ( - "os" "reflect" "testing" ) func TestBlame(t *testing.T) { repo := createTestRepo(t) - defer repo.Free() - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) commitId1, _ := seedTestRepo(t, repo) commitId2, _ := updateReadme(t, repo, "foo\nbar\nbaz\n") diff --git a/blob_test.go b/blob_test.go index e075192..2b5ec4f 100644 --- a/blob_test.go +++ b/blob_test.go @@ -1,13 +1,12 @@ package git import ( - "os" "testing" ) func TestCreateBlobFromBuffer(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) id, err := repo.CreateBlobFromBuffer(make([]byte, 0)) checkFatal(t, err) diff --git a/branch_test.go b/branch_test.go index 09ebeba..a0834a8 100644 --- a/branch_test.go +++ b/branch_test.go @@ -1,9 +1,13 @@ package git -import "testing" +import ( + "testing" +) func TestBranchIterator(t *testing.T) { repo := createTestRepo(t) + defer cleanupTestRepo(t, repo) + seedTestRepo(t, repo) i, err := repo.NewBranchIterator(BranchLocal) @@ -24,6 +28,8 @@ func TestBranchIterator(t *testing.T) { func TestBranchIteratorEach(t *testing.T) { repo := createTestRepo(t) + defer cleanupTestRepo(t, repo) + seedTestRepo(t, repo) i, err := repo.NewBranchIterator(BranchLocal) diff --git a/cherrypick_test.go b/cherrypick_test.go index f06dbdd..09bc524 100644 --- a/cherrypick_test.go +++ b/cherrypick_test.go @@ -34,6 +34,8 @@ func readReadme(t *testing.T, repo *Repository) string { func TestCherrypick(t *testing.T) { repo := createTestRepo(t) + defer cleanupTestRepo(t, repo) + c1, _ := seedTestRepo(t, repo) c2, _ := updateReadme(t, repo, content) diff --git a/clone_test.go b/clone_test.go index 97366bf..fd83fec 100644 --- a/clone_test.go +++ b/clone_test.go @@ -2,22 +2,21 @@ package git import ( "io/ioutil" - "os" "testing" ) func TestClone(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) seedTestRepo(t, repo) path, err := ioutil.TempDir("", "git2go") checkFatal(t, err) - _, err = Clone(repo.Path(), path, &CloneOptions{Bare: true}) - defer os.RemoveAll(path) + repo2, err := Clone(repo.Path(), path, &CloneOptions{Bare: true}) + defer cleanupTestRepo(t, repo2) checkFatal(t, err) } diff --git a/diff_test.go b/diff_test.go index fc6fed9..464fae6 100644 --- a/diff_test.go +++ b/diff_test.go @@ -2,15 +2,13 @@ package git import ( "errors" - "os" "strings" "testing" ) func TestFindSimilar(t *testing.T) { repo := createTestRepo(t) - defer repo.Free() - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) originalTree, newTree := createTestTrees(t, repo) @@ -65,8 +63,7 @@ func TestFindSimilar(t *testing.T) { func TestDiffTreeToTree(t *testing.T) { repo := createTestRepo(t) - defer repo.Free() - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) originalTree, newTree := createTestTrees(t, repo) diff --git a/git_test.go b/git_test.go index b9cf0a9..58caf71 100644 --- a/git_test.go +++ b/git_test.go @@ -2,11 +2,24 @@ package git import ( "io/ioutil" + "os" "path" "testing" "time" ) +func cleanupTestRepo(t *testing.T, r *Repository) { + var err error + if r.IsBare() { + err = os.RemoveAll(r.Path()) + } else { + err = os.RemoveAll(r.Workdir()) + } + checkFatal(t, err) + + r.Free() +} + func createTestRepo(t *testing.T) *Repository { // figure out where we can create the test repo path, err := ioutil.TempDir("", "git2go") diff --git a/index_test.go b/index_test.go index 98d9a31..647a0b8 100644 --- a/index_test.go +++ b/index_test.go @@ -2,14 +2,13 @@ package git import ( "io/ioutil" - "os" "runtime" "testing" ) func TestCreateRepoAndStage(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) idx, err := repo.Index() checkFatal(t, err) @@ -25,10 +24,10 @@ func TestCreateRepoAndStage(t *testing.T) { func TestIndexWriteTreeTo(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) repo2 := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo2) idx, err := repo.Index() checkFatal(t, err) @@ -44,7 +43,7 @@ func TestIndexWriteTreeTo(t *testing.T) { func TestIndexAddAndWriteTreeTo(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) odb, err := repo.Odb() checkFatal(t, err) @@ -74,7 +73,7 @@ func TestIndexAddAndWriteTreeTo(t *testing.T) { func TestIndexAddAllNoCallback(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) err := ioutil.WriteFile(repo.Workdir()+"/README", []byte("foo\n"), 0644) checkFatal(t, err) @@ -95,7 +94,7 @@ func TestIndexAddAllNoCallback(t *testing.T) { func TestIndexAddAllCallback(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) err := ioutil.WriteFile(repo.Workdir()+"/README", []byte("foo\n"), 0644) checkFatal(t, err) diff --git a/merge_test.go b/merge_test.go index 1eba806..0b1faca 100644 --- a/merge_test.go +++ b/merge_test.go @@ -1,13 +1,13 @@ package git import ( - "os" "testing" ) func TestMergeWithSelf(t *testing.T) { - repo := createTestRepo(t) + defer cleanupTestRepo(t, repo) + seedTestRepo(t, repo) master, err := repo.LookupReference("refs/heads/master") @@ -23,8 +23,9 @@ func TestMergeWithSelf(t *testing.T) { } func TestMergeAnalysisWithSelf(t *testing.T) { - repo := createTestRepo(t) + defer cleanupTestRepo(t, repo) + seedTestRepo(t, repo) master, err := repo.LookupReference("refs/heads/master") @@ -44,7 +45,6 @@ func TestMergeAnalysisWithSelf(t *testing.T) { } func TestMergeSameFile(t *testing.T) { - file := MergeFileInput{ Path: "test", Mode: 33188, @@ -68,8 +68,7 @@ func TestMergeSameFile(t *testing.T) { } func TestMergeTreesWithoutAncestor(t *testing.T) { repo := createTestRepo(t) - defer repo.Free() - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) _, originalTreeId := seedTestRepo(t, repo) originalTree, err := repo.LookupTree(originalTreeId) diff --git a/note_test.go b/note_test.go index f5e9c01..e6c378d 100644 --- a/note_test.go +++ b/note_test.go @@ -2,7 +2,6 @@ package git import ( "fmt" - "os" "reflect" "testing" "time" @@ -10,7 +9,7 @@ import ( func TestCreateNote(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) commitId, _ := seedTestRepo(t, repo) @@ -29,7 +28,8 @@ func TestCreateNote(t *testing.T) { func TestNoteIterator(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) + seedTestRepo(t, repo) notes := make([]*Note, 5) @@ -64,7 +64,7 @@ func TestNoteIterator(t *testing.T) { func TestRemoveNote(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) commitId, _ := seedTestRepo(t, repo) @@ -87,7 +87,7 @@ func TestRemoveNote(t *testing.T) { func TestDefaultNoteRef(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) ref, err := repo.DefaultNoteRef() checkFatal(t, err) diff --git a/object_test.go b/object_test.go index f525351..aa295e5 100644 --- a/object_test.go +++ b/object_test.go @@ -1,13 +1,13 @@ package git import ( - "os" "testing" ) func TestObjectPoymorphism(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) + commitId, treeId := seedTestRepo(t, repo) var obj Object @@ -89,7 +89,8 @@ func checkOwner(t *testing.T, repo *Repository, obj Object) { func TestObjectOwner(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) + commitId, treeId := seedTestRepo(t, repo) commit, err := repo.LookupCommit(commitId) diff --git a/odb_test.go b/odb_test.go index 5e6b7ff..55ed297 100644 --- a/odb_test.go +++ b/odb_test.go @@ -3,13 +3,13 @@ package git import ( "errors" "io" - "os" "testing" ) func TestOdbStream(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) + _, _ = seedTestRepo(t, repo) odb, error := repo.Odb() @@ -38,7 +38,8 @@ func TestOdbStream(t *testing.T) { func TestOdbHash(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) + _, _ = seedTestRepo(t, repo) odb, error := repo.Odb() @@ -64,7 +65,8 @@ Initial commit.` func TestOdbForeach(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) + _, _ = seedTestRepo(t, repo) odb, err := repo.Odb() diff --git a/patch_test.go b/patch_test.go index a061142..2d52fb4 100644 --- a/patch_test.go +++ b/patch_test.go @@ -7,8 +7,7 @@ import ( func TestPatch(t *testing.T) { repo := createTestRepo(t) - defer repo.Free() - //defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) _, originalTreeId := seedTestRepo(t, repo) originalTree, err := repo.LookupTree(originalTreeId) diff --git a/push_test.go b/push_test.go index cd708c6..e36e407 100644 --- a/push_test.go +++ b/push_test.go @@ -1,15 +1,15 @@ package git import ( - "os" "testing" ) func TestRemotePush(t *testing.T) { repo := createBareTestRepo(t) - defer os.RemoveAll(repo.Path()) + defer cleanupTestRepo(t, repo) + localRepo := createTestRepo(t) - defer os.RemoveAll(localRepo.Workdir()) + defer cleanupTestRepo(t, localRepo) remote, err := localRepo.CreateRemote("test_push", repo.Path()) checkFatal(t, err) diff --git a/reference_test.go b/reference_test.go index c7d52fb..d6b5f22 100644 --- a/reference_test.go +++ b/reference_test.go @@ -1,7 +1,6 @@ package git import ( - "os" "runtime" "sort" "testing" @@ -10,7 +9,7 @@ import ( func TestRefModification(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) commitId, treeId := seedTestRepo(t, repo) @@ -62,7 +61,7 @@ func TestRefModification(t *testing.T) { func TestReferenceIterator(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) loc, err := time.LoadLocation("Europe/Berlin") checkFatal(t, err) @@ -140,7 +139,8 @@ func TestReferenceIterator(t *testing.T) { func TestReferenceOwner(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) + commitId, _ := seedTestRepo(t, repo) ref, err := repo.CreateReference("refs/heads/foo", commitId, true, nil, "") @@ -158,7 +158,7 @@ func TestReferenceOwner(t *testing.T) { func TestUtil(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) commitId, _ := seedTestRepo(t, repo) diff --git a/remote_test.go b/remote_test.go index 54a66ed..25ee13d 100644 --- a/remote_test.go +++ b/remote_test.go @@ -2,15 +2,13 @@ package git import ( "fmt" - "os" "testing" "time" ) func TestRefspecs(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) - defer repo.Free() + defer cleanupTestRepo(t, repo) remote, err := repo.CreateAnonymousRemote("git://foo/bar", "refs/heads/*:refs/heads/*") checkFatal(t, err) @@ -31,8 +29,7 @@ func TestRefspecs(t *testing.T) { func TestListRemotes(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) - defer repo.Free() + defer cleanupTestRepo(t, repo) _, err := repo.CreateRemote("test", "git://foo/bar") @@ -59,8 +56,7 @@ func assertHostname(cert *Certificate, valid bool, hostname string, t *testing.T func TestCertificateCheck(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) - defer repo.Free() + defer cleanupTestRepo(t, repo) remote, err := repo.CreateRemote("origin", "https://github.com/libgit2/TestGitRepository") checkFatal(t, err) @@ -79,8 +75,7 @@ func TestCertificateCheck(t *testing.T) { func TestRemoteConnect(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) - defer repo.Free() + defer cleanupTestRepo(t, repo) remote, err := repo.CreateRemote("origin", "https://github.com/libgit2/TestGitRepository") checkFatal(t, err) @@ -91,8 +86,7 @@ func TestRemoteConnect(t *testing.T) { func TestRemoteLs(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) - defer repo.Free() + defer cleanupTestRepo(t, repo) remote, err := repo.CreateRemote("origin", "https://github.com/libgit2/TestGitRepository") checkFatal(t, err) @@ -110,8 +104,7 @@ func TestRemoteLs(t *testing.T) { func TestRemoteLsFiltering(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) - defer repo.Free() + defer cleanupTestRepo(t, repo) remote, err := repo.CreateRemote("origin", "https://github.com/libgit2/TestGitRepository") checkFatal(t, err) @@ -137,8 +130,7 @@ func TestRemoteLsFiltering(t *testing.T) { func TestRemotePruneRefs(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) - defer repo.Free() + defer cleanupTestRepo(t, repo) config, err := repo.Config() checkFatal(t, err) @@ -160,8 +152,7 @@ func TestRemotePruneRefs(t *testing.T) { func TestRemotePrune(t *testing.T) { remoteRepo := createTestRepo(t) - defer os.RemoveAll(remoteRepo.Workdir()) - defer remoteRepo.Free() + defer cleanupTestRepo(t, remoteRepo) head, _ := seedTestRepo(t, remoteRepo) commit, err := remoteRepo.LookupCommit(head) @@ -178,8 +169,7 @@ func TestRemotePrune(t *testing.T) { checkFatal(t, err) repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) - defer repo.Free() + defer cleanupTestRepo(t, repo) config, err := repo.Config() checkFatal(t, err) diff --git a/revparse_test.go b/revparse_test.go index c046a20..2ccdca2 100644 --- a/revparse_test.go +++ b/revparse_test.go @@ -1,13 +1,12 @@ package git import ( - "os" "testing" ) func TestRevparse(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) commitId, _ := seedTestRepo(t, repo) @@ -19,7 +18,7 @@ func TestRevparse(t *testing.T) { func TestRevparseSingle(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) commitId, _ := seedTestRepo(t, repo) @@ -31,7 +30,7 @@ func TestRevparseSingle(t *testing.T) { func TestRevparseExt(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) _, treeId := seedTestRepo(t, repo) diff --git a/status_test.go b/status_test.go index d18fca1..5b97b00 100644 --- a/status_test.go +++ b/status_test.go @@ -2,15 +2,13 @@ package git import ( "io/ioutil" - "os" "path" "testing" ) func TestStatusFile(t *testing.T) { repo := createTestRepo(t) - defer repo.Free() - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) state := repo.State() if state != RepositoryStateNone { @@ -30,10 +28,10 @@ func TestStatusFile(t *testing.T) { func TestStatusList(t *testing.T) { repo := createTestRepo(t) + defer cleanupTestRepo(t, repo) + // 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) diff --git a/submodule_test.go b/submodule_test.go index 1c8f471..ee75d53 100644 --- a/submodule_test.go +++ b/submodule_test.go @@ -6,6 +6,8 @@ import ( func TestSubmoduleForeach(t *testing.T) { repo := createTestRepo(t) + defer cleanupTestRepo(t, repo) + seedTestRepo(t, repo) _, err := repo.AddSubmodule("http://example.org/submodule", "submodule", true) diff --git a/tag_test.go b/tag_test.go index 126cf6e..74f9fec 100644 --- a/tag_test.go +++ b/tag_test.go @@ -1,14 +1,14 @@ package git import ( - "os" "testing" "time" ) func TestCreateTag(t *testing.T) { repo := createTestRepo(t) - defer os.RemoveAll(repo.Workdir()) + defer cleanupTestRepo(t, repo) + commitId, _ := seedTestRepo(t, repo) commit, err := repo.LookupCommit(commitId) From a8ad0d204052d8bd9c4d0093cce62c54afa67188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 19 May 2015 14:33:30 +0200 Subject: [PATCH 09/11] Index: Add ReadTree() --- index.go | 14 ++++++++++++++ index_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/index.go b/index.go index 9f37f33..009aeb6 100644 --- a/index.go +++ b/index.go @@ -240,6 +240,20 @@ func (v *Index) WriteTreeTo(repo *Repository) (*Oid, error) { return oid, nil } +// ReadTree replaces the contents of the index with those of the given +// tree +func (v *Index) ReadTree(tree *Tree) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_index_read_tree(v.ptr, tree.cast_ptr); + if ret < 0 { + return MakeGitError(ret) + } + + return nil +} + func (v *Index) WriteTree() (*Oid, error) { oid := new(Oid) diff --git a/index_test.go b/index_test.go index 647a0b8..a1f0c9c 100644 --- a/index_test.go +++ b/index_test.go @@ -22,6 +22,34 @@ func TestCreateRepoAndStage(t *testing.T) { } } +func TestIndexReadTree(t *testing.T) { + repo := createTestRepo(t) + defer cleanupTestRepo(t, repo) + + _, _ = seedTestRepo(t, repo) + + ref, err := repo.Head() + checkFatal(t, err) + + obj, err := ref.Peel(ObjectTree); + checkFatal(t, err) + + tree := obj.(*Tree) + + idx, err := NewIndex() + checkFatal(t, err) + + err = idx.ReadTree(tree) + checkFatal(t, err) + + id, err := idx.WriteTreeTo(repo) + checkFatal(t, err) + + if tree.Id().Cmp(id) != 0 { + t.Fatalf("Read and written trees are not the same") + } +} + func TestIndexWriteTreeTo(t *testing.T) { repo := createTestRepo(t) defer cleanupTestRepo(t, repo) From d7a0495000e35d06993605a9a31a5f9823292f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 19 May 2015 14:56:01 +0200 Subject: [PATCH 10/11] Index: Add OpenIndex This lets you persist an index at an arbitrary location. --- index.go | 18 ++++++++++++++++++ index_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/index.go b/index.go index 009aeb6..2082ebd 100644 --- a/index.go +++ b/index.go @@ -96,6 +96,24 @@ func NewIndex() (*Index, error) { return &Index{ptr: ptr}, nil } +// OpenIndex creates a new index at the given path. If the file does +// not exist it will be created when Write() is called. +func OpenIndex(path string) (*Index, error) { + var ptr *C.git_index + + var cpath = C.CString(path) + defer C.free(unsafe.Pointer(cpath)) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + if err := C.git_index_open(&ptr, cpath); err < 0 { + return nil, MakeGitError(err) + } + + return &Index{ptr: ptr}, nil +} + // Add adds or replaces the given entry to the index, making a copy of // the data func (v *Index) Add(entry *IndexEntry) error { diff --git a/index_test.go b/index_test.go index a1f0c9c..9b54945 100644 --- a/index_test.go +++ b/index_test.go @@ -2,6 +2,7 @@ package git import ( "io/ioutil" + "os" "runtime" "testing" ) @@ -148,6 +149,29 @@ func TestIndexAddAllCallback(t *testing.T) { } } +func TestIndexOpen(t *testing.T) { + repo := createTestRepo(t) + defer cleanupTestRepo(t, repo) + + path := repo.Workdir() + "/heyindex" + + _, err := os.Stat(path) + if !os.IsNotExist(err) { + t.Fatal("new index file already exists") + } + + idx, err := OpenIndex(path) + checkFatal(t, err) + + err = idx.Write() + checkFatal(t, err) + + _, err = os.Stat(path) + if os.IsNotExist(err) { + t.Fatal("new index file did not get written") + } +} + func checkFatal(t *testing.T, err error) { if err == nil { return From 72c19f73c9170720780839cd1561486e075d35a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 19 May 2015 15:05:00 +0200 Subject: [PATCH 11/11] Index: Add Path() accessor --- index.go | 6 ++++++ index_test.go | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/index.go b/index.go index 2082ebd..1a899f1 100644 --- a/index.go +++ b/index.go @@ -114,6 +114,12 @@ func OpenIndex(path string) (*Index, error) { return &Index{ptr: ptr}, nil } +// Path returns the index' path on disk or an empty string if it +// exists only in memory. +func (v *Index) Path() string { + return C.GoString(C.git_index_path(v.ptr)) +} + // Add adds or replaces the given entry to the index, making a copy of // the data func (v *Index) Add(entry *IndexEntry) error { diff --git a/index_test.go b/index_test.go index 9b54945..9283b83 100644 --- a/index_test.go +++ b/index_test.go @@ -83,6 +83,10 @@ func TestIndexAddAndWriteTreeTo(t *testing.T) { idx, err := NewIndex() checkFatal(t, err) + if idx.Path() != "" { + t.Fatal("in-memory repo has a path") + } + entry := IndexEntry{ Path: "README", Id: blobID, @@ -163,6 +167,10 @@ func TestIndexOpen(t *testing.T) { idx, err := OpenIndex(path) checkFatal(t, err) + if path != idx.Path() { + t.Fatalf("mismatched index paths, expected %v, got %v", path, idx.Path()) + } + err = idx.Write() checkFatal(t, err)