summaryrefslogtreecommitdiff
path: root/commit.go
blob: fc04e1e56afc8b62d719a39c9e02e2094b170f23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package git

/*
#include <git2.h>

extern int _go_git_treewalk(git_tree *tree, git_treewalk_mode mode, void *ptr);
*/
import "C"

import (
	"runtime"
	"unsafe"
)

// Commit
type Commit struct {
	Object
	cast_ptr *C.git_commit
}

func (c Commit) Message() string {
	return C.GoString(C.git_commit_message(c.cast_ptr))
}

func (c Commit) RawMessage() string {
	return C.GoString(C.git_commit_message_raw(c.cast_ptr))
}

func (c Commit) ExtractSignature() (string, string, error) {

	var c_signed C.git_buf
	defer C.git_buf_free(&c_signed)

	var c_signature C.git_buf
	defer C.git_buf_free(&c_signature)

	oid := c.Id()
	repo := C.git_commit_owner(c.cast_ptr)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()
	ret := C.git_commit_extract_signature(&c_signature, &c_signed, repo, oid.toC(), nil)

	if ret < 0 {
		return "", "", MakeGitError(ret)
	} else {
		return C.GoString(c_signature.ptr), C.GoString(c_signed.ptr), nil
	}

}

func (c Commit) Summary() string {
	return C.GoString(C.git_commit_summary(c.cast_ptr))
}

func (c Commit) Tree() (*Tree, error) {
	var ptr *C.git_tree

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	err := C.git_commit_tree(&ptr, c.cast_ptr)
	if err < 0 {
		return nil, MakeGitError(err)
	}

	return allocTree(ptr, c.repo), nil
}

func (c Commit) TreeId() *Oid {
	return newOidFromC(C.git_commit_tree_id(c.cast_ptr))
}

func (c Commit) Author() *Signature {
	cast_ptr := C.git_commit_author(c.cast_ptr)
	return newSignatureFromC(cast_ptr)
}

func (c Commit) Committer() *Signature {
	cast_ptr := C.git_commit_committer(c.cast_ptr)
	return newSignatureFromC(cast_ptr)
}

func (c *Commit) Parent(n uint) *Commit {
	var cobj *C.git_commit
	ret := C.git_commit_parent(&cobj, c.cast_ptr, C.uint(n))
	if ret != 0 {
		return nil
	}

	return allocCommit(cobj, c.repo)
}

func (c *Commit) ParentId(n uint) *Oid {
	return newOidFromC(C.git_commit_parent_id(c.cast_ptr, C.uint(n)))
}

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
}