summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlhchavez <[email protected]>2021-09-04 13:04:58 -0700
committerGitHub <[email protected]>2021-09-04 13:04:58 -0700
commitfbaf9d1d1ae0bb7b6e7ed9044945d4c9322d4c76 (patch)
tree8d93d7f0a2d983e99b931ed4a8d9e904add20a0a
parentdf7084d36a771e4ef2a418c7d3c4367d920e4cf3 (diff)
Add `Repository.CreateCommitBuffer` (#781)
This commit adds the Go binding for `git_commit_create_buffer`. This will be used to support the 1.2.0 commit create callback.
-rw-r--r--commit.go8
-rw-r--r--repository.go63
-rw-r--r--repository_test.go54
3 files changed, 125 insertions, 0 deletions
diff --git a/commit.go b/commit.go
index 1c546b3..3a07fa8 100644
--- a/commit.go
+++ b/commit.go
@@ -12,6 +12,14 @@ import (
"unsafe"
)
+// MessageEncoding is the encoding of commit messages.
+type MessageEncoding string
+
+const (
+ // MessageEncodingUTF8 is the default message encoding.
+ MessageEncodingUTF8 MessageEncoding = "UTF-8"
+)
+
// Commit
type Commit struct {
Object
diff --git a/repository.go b/repository.go
index cb82fc3..dc40aaf 100644
--- a/repository.go
+++ b/repository.go
@@ -485,6 +485,69 @@ func (v *Repository) CreateCommit(
return oid, nil
}
+// CreateCommitBuffer creates a commit and write it into a buffer.
+func (v *Repository) CreateCommitBuffer(
+ author, committer *Signature,
+ messageEncoding MessageEncoding,
+ message string,
+ tree *Tree,
+ parents ...*Commit,
+) ([]byte, error) {
+ cmsg := C.CString(message)
+ defer C.free(unsafe.Pointer(cmsg))
+ var cencoding *C.char
+ // Since the UTF-8 encoding is the default, pass in nil whenever UTF-8 is
+ // provided. That will cause the commit to not have an explicit header for
+ // it.
+ if messageEncoding != MessageEncodingUTF8 && messageEncoding != MessageEncoding("") {
+ cencoding = C.CString(string(messageEncoding))
+ defer C.free(unsafe.Pointer(cencoding))
+ }
+
+ var cparents []*C.git_commit = nil
+ var parentsarg **C.git_commit = nil
+
+ nparents := len(parents)
+ if nparents > 0 {
+ cparents = make([]*C.git_commit, nparents)
+ for i, v := range parents {
+ cparents[i] = v.cast_ptr
+ }
+ parentsarg = &cparents[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()
+
+ var buf C.git_buf
+ defer C.git_buf_dispose(&buf)
+ ret := C.git_commit_create_buffer(
+ &buf, v.ptr,
+ authorSig, committerSig,
+ cencoding, cmsg, tree.cast_ptr, C.size_t(nparents), parentsarg)
+
+ runtime.KeepAlive(v)
+ runtime.KeepAlive(buf)
+ runtime.KeepAlive(parents)
+ if ret < 0 {
+ return nil, MakeGitError(ret)
+ }
+
+ return C.GoBytes(unsafe.Pointer(buf.ptr), C.int(buf.size)), nil
+}
+
func (v *Repository) CreateCommitFromIds(
refname string, author, committer *Signature,
message string, tree *Oid, parents ...*Oid) (*Oid, error) {
diff --git a/repository_test.go b/repository_test.go
index e403aa9..60758c1 100644
--- a/repository_test.go
+++ b/repository_test.go
@@ -5,6 +5,60 @@ import (
"time"
)
+func TestCreateCommitBuffer(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: "[email protected]",
+ 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)
+
+ for encoding, expected := range map[MessageEncoding]string{
+ MessageEncodingUTF8: `tree b7119b11e8ef7a1a5a34d3ac87f5b075228ac81e
+author Rand Om Hacker <[email protected]> 1362576600 +0100
+committer Rand Om Hacker <[email protected]> 1362576600 +0100
+
+This is a commit
+`,
+ MessageEncoding("ASCII"): `tree b7119b11e8ef7a1a5a34d3ac87f5b075228ac81e
+author Rand Om Hacker <[email protected]> 1362576600 +0100
+committer Rand Om Hacker <[email protected]> 1362576600 +0100
+encoding ASCII
+
+This is a commit
+`,
+ } {
+ encoding := encoding
+ expected := expected
+ t.Run(string(encoding), func(t *testing.T) {
+ buf, err := repo.CreateCommitBuffer(sig, sig, encoding, message, tree)
+ checkFatal(t, err)
+
+ if expected != string(buf) {
+ t.Errorf("mismatched commit buffer, expected %v, got %v", expected, string(buf))
+ }
+ })
+ }
+}
+
func TestCreateCommitFromIds(t *testing.T) {
t.Parallel()
repo := createTestRepo(t)