From a119b21dbb1b3b2720a269ed6253b3e76764c7c8 Mon Sep 17 00:00:00 2001 From: reujab Date: Tue, 11 Jul 2017 23:52:13 -0400 Subject: fixed typos --- repository.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'repository.go') diff --git a/repository.go b/repository.go index abf8b71..d8de97a 100644 --- a/repository.go +++ b/repository.go @@ -19,10 +19,10 @@ type Repository struct { Remotes RemoteCollection // Submodules represents the collection of submodules and can // be used to add, remove and configure submodules in this - // repostiory. + // repository. Submodules SubmoduleCollection // References represents the collection of references and can - // be used to create, remove or update refernces for this repository. + // be used to create, remove or update references for this repository. References ReferenceCollection // Notes represents the collection of notes and can be used to // read, write and delete notes from this repository. -- cgit v1.2.3 From 8ff5e4371117994a7d9061128837f8c73317c527 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sat, 18 Aug 2018 00:46:30 +0000 Subject: Add support for CreateCommitFromIds This change adds support for CreateCommitFromIds from libgit2. --- repository.go | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'repository.go') diff --git a/repository.go b/repository.go index d8de97a..a430751 100644 --- a/repository.go +++ b/repository.go @@ -3,6 +3,8 @@ package git /* #include #include +#include +#include */ import "C" import ( @@ -389,6 +391,66 @@ func (v *Repository) CreateCommit( return oid, nil } +func (v *Repository) CreateCommitFromIds( + refname string, author, committer *Signature, + message string, tree *Oid, parents ...*Oid) (*Oid, error) { + + oid := new(Oid) + + 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)) + + var parentsarg **C.git_oid = nil + + nparents := len(parents) + if nparents > 0 { + parentsarg = (**C.git_oid)(C.malloc(C.size_t(unsafe.Sizeof(uintptr(0)) * uintptr(nparents)))) + defer C.free(unsafe.Pointer(parentsarg)) + parentsptr := uintptr(unsafe.Pointer(parentsarg)) + for _, v := range parents { + *(**C.git_oid)(unsafe.Pointer(parentsptr)) = v.toC() + parentsptr += unsafe.Sizeof(uintptr(0)) + } + } + + 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) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_commit_create_from_ids( + oid.toC(), v.ptr, cref, + authorSig, committerSig, + nil, cmsg, tree.toC(), C.size_t(nparents), parentsarg) + + runtime.KeepAlive(v) + runtime.KeepAlive(oid) + runtime.KeepAlive(parents) + if ret < 0 { + return nil, MakeGitError(ret) + } + + return oid, nil +} + func (v *Odb) Free() { runtime.SetFinalizer(v, nil) C.git_odb_free(v.ptr) -- cgit v1.2.3 From ee6dff2f8e3b130dee5e888f18cae0f74c35e8cd Mon Sep 17 00:00:00 2001 From: Carlos Martín Nieto Date: Sat, 5 Jan 2019 10:45:30 +0000 Subject: Use git_object_t instead of deprecated git_otype --- object.go | 14 +++++++------- odb.go | 12 ++++++------ reference.go | 2 +- repository.go | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) (limited to 'repository.go') diff --git a/object.go b/object.go index 66a4618..40ab2bf 100644 --- a/object.go +++ b/object.go @@ -13,12 +13,12 @@ import ( type ObjectType int const ( - ObjectAny ObjectType = C.GIT_OBJ_ANY - ObjectBad ObjectType = C.GIT_OBJ_BAD - ObjectCommit ObjectType = C.GIT_OBJ_COMMIT - ObjectTree ObjectType = C.GIT_OBJ_TREE - ObjectBlob ObjectType = C.GIT_OBJ_BLOB - ObjectTag ObjectType = C.GIT_OBJ_TAG + ObjectAny ObjectType = C.GIT_OBJECT_ANY + ObjectBad ObjectType = C.GIT_OBJECT_BAD + ObjectCommit ObjectType = C.GIT_OBJECT_COMMIT + ObjectTree ObjectType = C.GIT_OBJECT_TREE + ObjectBlob ObjectType = C.GIT_OBJECT_BLOB + ObjectTag ObjectType = C.GIT_OBJECT_TAG ) type Object struct { @@ -217,7 +217,7 @@ func (o *Object) Peel(t ObjectType) (*Object, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() - err := C.git_object_peel(&cobj, o.ptr, C.git_otype(t)) + err := C.git_object_peel(&cobj, o.ptr, C.git_object_t(t)) runtime.KeepAlive(o) if err < 0 { return nil, MakeGitError(err) diff --git a/odb.go b/odb.go index 7ae108a..5768cf4 100644 --- a/odb.go +++ b/odb.go @@ -61,12 +61,12 @@ func (v *Odb) ReadHeader(oid *Oid) (uint64, ObjectType, error) { defer runtime.UnlockOSThread() var sz C.size_t - var cotype C.git_otype + var cotype C.git_object_t ret := C.git_odb_read_header(&sz, &cotype, v.ptr, oid.toC()) runtime.KeepAlive(v) if ret < 0 { - return 0, C.GIT_OBJ_BAD, MakeGitError(ret) + return 0, ObjectBad, MakeGitError(ret) } return uint64(sz), ObjectType(cotype), nil @@ -93,7 +93,7 @@ func (v *Odb) Write(data []byte, otype ObjectType) (oid *Oid, err error) { size = C.size_t(0) } - ret := C.git_odb_write(oid.toC(), v.ptr, unsafe.Pointer(&data[0]), size, C.git_otype(otype)) + ret := C.git_odb_write(oid.toC(), v.ptr, unsafe.Pointer(&data[0]), size, C.git_object_t(otype)) runtime.KeepAlive(v) if ret < 0 { return nil, MakeGitError(ret) @@ -181,7 +181,7 @@ func (v *Odb) Hash(data []byte, otype ObjectType) (oid *Oid, err error) { size = C.size_t(0) } - ret := C.git_odb_hash(oid.toC(), unsafe.Pointer(&data[0]), size, C.git_otype(otype)) + ret := C.git_odb_hash(oid.toC(), unsafe.Pointer(&data[0]), size, C.git_object_t(otype)) runtime.KeepAlive(data) if ret < 0 { return nil, MakeGitError(ret) @@ -193,7 +193,7 @@ func (v *Odb) Hash(data []byte, otype ObjectType) (oid *Oid, err error) { // contents of the object. func (v *Odb) NewReadStream(id *Oid) (*OdbReadStream, error) { stream := new(OdbReadStream) - var ctype C.git_otype + var ctype C.git_object_t var csize C.size_t runtime.LockOSThread() @@ -221,7 +221,7 @@ func (v *Odb) NewWriteStream(size int64, otype ObjectType) (*OdbWriteStream, err runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_odb_open_wstream(&stream.ptr, v.ptr, C.git_off_t(size), C.git_otype(otype)) + ret := C.git_odb_open_wstream(&stream.ptr, v.ptr, C.git_off_t(size), C.git_object_t(otype)) runtime.KeepAlive(v) if ret < 0 { return nil, MakeGitError(ret) diff --git a/reference.go b/reference.go index 12ecb74..b5f5e47 100644 --- a/reference.go +++ b/reference.go @@ -284,7 +284,7 @@ func (v *Reference) Peel(t ObjectType) (*Object, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() - err := C.git_reference_peel(&cobj, v.ptr, C.git_otype(t)) + err := C.git_reference_peel(&cobj, v.ptr, C.git_object_t(t)) runtime.KeepAlive(v) if err < 0 { return nil, MakeGitError(err) diff --git a/repository.go b/repository.go index d8de97a..74924b7 100644 --- a/repository.go +++ b/repository.go @@ -174,7 +174,7 @@ func (v *Repository) lookupType(id *Oid, t ObjectType) (*Object, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_object_lookup(&ptr, v.ptr, id.toC(), C.git_otype(t)) + ret := C.git_object_lookup(&ptr, v.ptr, id.toC(), C.git_object_t(t)) runtime.KeepAlive(id) if ret < 0 { return nil, MakeGitError(ret) -- cgit v1.2.3 From f505e39c9eac64264d6341cc925c5fa7f67b56cf Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sat, 5 Jan 2019 20:13:01 +0000 Subject: Add a test and some comments as to the ugly pointer arithmetic --- repository.go | 11 +++++++++-- repository_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 repository_test.go (limited to 'repository.go') diff --git a/repository.go b/repository.go index a430751..30673a7 100644 --- a/repository.go +++ b/repository.go @@ -412,12 +412,19 @@ func (v *Repository) CreateCommitFromIds( nparents := len(parents) if nparents > 0 { - parentsarg = (**C.git_oid)(C.malloc(C.size_t(unsafe.Sizeof(uintptr(0)) * uintptr(nparents)))) + // All this awful pointer arithmetic is needed to avoid passing a Go + // pointer to Go pointer into C. Other methods (like CreateCommits) are + // fine without this workaround because they are just passing Go pointers + // to C pointers, but arrays-of-pointers-to-git_oid are a bit special since + // both the array and the objects are allocated from Go. + var emptyOidPtr *C.git_oid + sizeofOidPtr := unsafe.Sizeof(emptyOidPtr) + parentsarg = (**C.git_oid)(C.calloc(C.size_t(uintptr(nparents)), C.size_t(sizeofOidPtr))) defer C.free(unsafe.Pointer(parentsarg)) parentsptr := uintptr(unsafe.Pointer(parentsarg)) for _, v := range parents { *(**C.git_oid)(unsafe.Pointer(parentsptr)) = v.toC() - parentsptr += unsafe.Sizeof(uintptr(0)) + parentsptr += sizeofOidPtr } } diff --git a/repository_test.go b/repository_test.go new file mode 100644 index 0000000..1950c69 --- /dev/null +++ b/repository_test.go @@ -0,0 +1,42 @@ +package git + +import ( + "testing" + "time" +) + +func TestCreateCommitFromIds(t *testing.T) { + t.Parallel() + repo := createTestRepo(t) + defer cleanupTestRepo(t, repo) + + loc, err := time.LoadLocation("Europe/Berlin") + checkFatal(t, err) + sig := &Signature{ + Name: "Rand Om Hacker", + Email: "random@hacker.com", + When: time.Date(2013, 03, 06, 14, 30, 0, 0, loc), + } + + idx, err := repo.Index() + checkFatal(t, err) + err = idx.AddByPath("README") + checkFatal(t, err) + err = idx.Write() + checkFatal(t, err) + treeId, err := idx.WriteTree() + checkFatal(t, err) + + message := "This is a commit\n" + tree, err := repo.LookupTree(treeId) + checkFatal(t, err) + expectedCommitId, err := repo.CreateCommit("HEAD", sig, sig, message, tree) + checkFatal(t, err) + + commitId, err := repo.CreateCommitFromIds("", sig, sig, message, treeId) + checkFatal(t, err) + + if !expectedCommitId.Equal(commitId) { + t.Errorf("mismatched commit ids, expected %v, got %v", expectedCommitId.String(), commitId.String()) + } +} -- cgit v1.2.3 From 35518c78df9ae727651212512bfaa1a8dae02585 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Tue, 8 Jan 2019 02:50:42 +0000 Subject: Keeping the tree alive --- repository.go | 1 + 1 file changed, 1 insertion(+) (limited to 'repository.go') diff --git a/repository.go b/repository.go index 30673a7..2a4e9c8 100644 --- a/repository.go +++ b/repository.go @@ -450,6 +450,7 @@ func (v *Repository) CreateCommitFromIds( runtime.KeepAlive(v) runtime.KeepAlive(oid) + runtime.KeepAlive(tree) runtime.KeepAlive(parents) if ret < 0 { return nil, MakeGitError(ret) -- cgit v1.2.3 From 2bb5930733a50b441c4a591dee931af00cf293f2 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sat, 16 Feb 2019 17:14:39 +0000 Subject: Free() the copies of repository.LookupXxx() `repository.LookupXxx()` allocate new go `Object`s that have a reference to a `C.git_object`. Those are then duplicated with `git_object_dup()`, so the original `Object`s linger unnecessarily until the Go GC kicks in. This change explicitly calls `Free()` on the originals to avoid unnecessary accumulation of garbage. --- repository.go | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'repository.go') diff --git a/repository.go b/repository.go index 3e0d20f..07b2605 100644 --- a/repository.go +++ b/repository.go @@ -194,6 +194,7 @@ func (v *Repository) LookupTree(id *Oid) (*Tree, error) { if err != nil { return nil, err } + defer obj.Free() return obj.AsTree() } @@ -203,6 +204,7 @@ func (v *Repository) LookupCommit(id *Oid) (*Commit, error) { if err != nil { return nil, err } + defer obj.Free() return obj.AsCommit() } @@ -212,6 +214,7 @@ func (v *Repository) LookupBlob(id *Oid) (*Blob, error) { if err != nil { return nil, err } + defer obj.Free() return obj.AsBlob() } @@ -221,6 +224,7 @@ func (v *Repository) LookupTag(id *Oid) (*Tag, error) { if err != nil { return nil, err } + defer obj.Free() return obj.AsTag() } -- cgit v1.2.3