Skip to content

Commit fbaf9d1

Browse files
authored
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.
1 parent df7084d commit fbaf9d1

File tree

3 files changed

+125
-0
lines changed

3 files changed

+125
-0
lines changed

commit.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ import (
1212
"unsafe"
1313
)
1414

15+
// MessageEncoding is the encoding of commit messages.
16+
type MessageEncoding string
17+
18+
const (
19+
// MessageEncodingUTF8 is the default message encoding.
20+
MessageEncodingUTF8 MessageEncoding = "UTF-8"
21+
)
22+
1523
// Commit
1624
type Commit struct {
1725
Object

repository.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,69 @@ func (v *Repository) CreateCommit(
485485
return oid, nil
486486
}
487487

488+
// CreateCommitBuffer creates a commit and write it into a buffer.
489+
func (v *Repository) CreateCommitBuffer(
490+
author, committer *Signature,
491+
messageEncoding MessageEncoding,
492+
message string,
493+
tree *Tree,
494+
parents ...*Commit,
495+
) ([]byte, error) {
496+
cmsg := C.CString(message)
497+
defer C.free(unsafe.Pointer(cmsg))
498+
var cencoding *C.char
499+
// Since the UTF-8 encoding is the default, pass in nil whenever UTF-8 is
500+
// provided. That will cause the commit to not have an explicit header for
501+
// it.
502+
if messageEncoding != MessageEncodingUTF8 && messageEncoding != MessageEncoding("") {
503+
cencoding = C.CString(string(messageEncoding))
504+
defer C.free(unsafe.Pointer(cencoding))
505+
}
506+
507+
var cparents []*C.git_commit = nil
508+
var parentsarg **C.git_commit = nil
509+
510+
nparents := len(parents)
511+
if nparents > 0 {
512+
cparents = make([]*C.git_commit, nparents)
513+
for i, v := range parents {
514+
cparents[i] = v.cast_ptr
515+
}
516+
parentsarg = &cparents[0]
517+
}
518+
519+
authorSig, err := author.toC()
520+
if err != nil {
521+
return nil, err
522+
}
523+
defer C.git_signature_free(authorSig)
524+
525+
committerSig, err := committer.toC()
526+
if err != nil {
527+
return nil, err
528+
}
529+
defer C.git_signature_free(committerSig)
530+
531+
runtime.LockOSThread()
532+
defer runtime.UnlockOSThread()
533+
534+
var buf C.git_buf
535+
defer C.git_buf_dispose(&buf)
536+
ret := C.git_commit_create_buffer(
537+
&buf, v.ptr,
538+
authorSig, committerSig,
539+
cencoding, cmsg, tree.cast_ptr, C.size_t(nparents), parentsarg)
540+
541+
runtime.KeepAlive(v)
542+
runtime.KeepAlive(buf)
543+
runtime.KeepAlive(parents)
544+
if ret < 0 {
545+
return nil, MakeGitError(ret)
546+
}
547+
548+
return C.GoBytes(unsafe.Pointer(buf.ptr), C.int(buf.size)), nil
549+
}
550+
488551
func (v *Repository) CreateCommitFromIds(
489552
refname string, author, committer *Signature,
490553
message string, tree *Oid, parents ...*Oid) (*Oid, error) {

repository_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,60 @@ import (
55
"time"
66
)
77

8+
func TestCreateCommitBuffer(t *testing.T) {
9+
t.Parallel()
10+
repo := createTestRepo(t)
11+
defer cleanupTestRepo(t, repo)
12+
13+
loc, err := time.LoadLocation("Europe/Berlin")
14+
checkFatal(t, err)
15+
sig := &Signature{
16+
Name: "Rand Om Hacker",
17+
Email: "random@hacker.com",
18+
When: time.Date(2013, 03, 06, 14, 30, 0, 0, loc),
19+
}
20+
21+
idx, err := repo.Index()
22+
checkFatal(t, err)
23+
err = idx.AddByPath("README")
24+
checkFatal(t, err)
25+
err = idx.Write()
26+
checkFatal(t, err)
27+
treeId, err := idx.WriteTree()
28+
checkFatal(t, err)
29+
30+
message := "This is a commit\n"
31+
tree, err := repo.LookupTree(treeId)
32+
checkFatal(t, err)
33+
34+
for encoding, expected := range map[MessageEncoding]string{
35+
MessageEncodingUTF8: `tree b7119b11e8ef7a1a5a34d3ac87f5b075228ac81e
36+
author Rand Om Hacker <random@hacker.com> 1362576600 +0100
37+
committer Rand Om Hacker <random@hacker.com> 1362576600 +0100
38+
39+
This is a commit
40+
`,
41+
MessageEncoding("ASCII"): `tree b7119b11e8ef7a1a5a34d3ac87f5b075228ac81e
42+
author Rand Om Hacker <random@hacker.com> 1362576600 +0100
43+
committer Rand Om Hacker <random@hacker.com> 1362576600 +0100
44+
encoding ASCII
45+
46+
This is a commit
47+
`,
48+
} {
49+
encoding := encoding
50+
expected := expected
51+
t.Run(string(encoding), func(t *testing.T) {
52+
buf, err := repo.CreateCommitBuffer(sig, sig, encoding, message, tree)
53+
checkFatal(t, err)
54+
55+
if expected != string(buf) {
56+
t.Errorf("mismatched commit buffer, expected %v, got %v", expected, string(buf))
57+
}
58+
})
59+
}
60+
}
61+
862
func TestCreateCommitFromIds(t *testing.T) {
963
t.Parallel()
1064
repo := createTestRepo(t)

0 commit comments

Comments
 (0)