Codebase list golang-gopkg-libgit2-git2go.v27 / f4ad4d8
Imported Upstream version 0.0~git20150623 Maximiliano Curia 8 years ago
16 changed file(s) with 231 addition(s) and 68 deletion(s). Raw diff Collapse all Expand all
5959 }
6060
6161 //export blobChunkCb
62 func blobChunkCb(buffer *C.char, maxLen C.size_t, payload unsafe.Pointer) int {
63 data := (*BlobCallbackData)(payload)
62 func blobChunkCb(buffer *C.char, maxLen C.size_t, handle unsafe.Pointer) int {
63 payload := pointerHandles.Get(handle)
64 data, ok := payload.(*BlobCallbackData)
65 if !ok {
66 panic("could not retrieve blob callback data")
67 }
68
6469 goBuf, err := data.Callback(int(maxLen))
6570 if err == io.EOF {
6671 return 0
8287 defer C.free(unsafe.Pointer(chintPath))
8388 }
8489 oid := C.git_oid{}
90
8591 payload := &BlobCallbackData{Callback: callback}
86 ecode := C._go_git_blob_create_fromchunks(&oid, repo.ptr, chintPath, unsafe.Pointer(payload))
92 handle := pointerHandles.Track(payload)
93 defer pointerHandles.Untrack(handle)
94
95 ecode := C._go_git_blob_create_fromchunks(&oid, repo.ptr, chintPath, handle)
8796 if payload.Error != nil {
8897 return nil, payload.Error
8998 }
9191
9292 func (repo *Repository) CreateBranch(branchName string, target *Commit, force bool, signature *Signature, msg string) (*Branch, error) {
9393
94 ref := new(Reference)
94 var ptr *C.git_reference
9595 cBranchName := C.CString(branchName)
9696 cForce := cbool(force)
9797
112112 runtime.LockOSThread()
113113 defer runtime.UnlockOSThread()
114114
115 ret := C.git_branch_create(&ref.ptr, repo.ptr, cBranchName, target.cast_ptr, cForce, cSignature, cmsg)
116 if ret < 0 {
117 return nil, MakeGitError(ret)
118 }
119 return ref.Branch(), nil
115 ret := C.git_branch_create(&ptr, repo.ptr, cBranchName, target.cast_ptr, cForce, cSignature, cmsg)
116 if ret < 0 {
117 return nil, MakeGitError(ret)
118 }
119 return newReferenceFromC(ptr, repo).Branch(), nil
120120 }
121121
122122 func (b *Branch) Delete() error {
2727 cpath := C.CString(path)
2828 defer C.free(unsafe.Pointer(cpath))
2929
30 var copts C.git_clone_options
31 populateCloneOptions(&copts, options)
32 defer freeCheckoutOpts(&copts.checkout_opts)
30 copts := (*C.git_clone_options)(C.calloc(1, C.size_t(unsafe.Sizeof(C.git_clone_options{}))))
31 populateCloneOptions(copts, options)
3332
3433 if len(options.CheckoutBranch) != 0 {
3534 copts.checkout_branch = C.CString(options.CheckoutBranch)
36 defer C.free(unsafe.Pointer(copts.checkout_branch))
3735 }
3836
3937 runtime.LockOSThread()
4038 defer runtime.UnlockOSThread()
41 ret := C.git_clone(&repo.ptr, curl, cpath, &copts)
39 ret := C.git_clone(&repo.ptr, curl, cpath, copts)
40 freeCheckoutOpts(&copts.checkout_opts)
41 C.free(unsafe.Pointer(copts.checkout_branch))
42 C.free(unsafe.Pointer(copts))
43
4244 if ret < 0 {
4345 return nil, MakeGitError(ret)
4446 }
264264 data := &diffForEachData{
265265 FileCallback: cbFile,
266266 }
267 ecode := C._go_git_diff_foreach(diff.ptr, 1, intHunks, intLines, unsafe.Pointer(data))
267
268 handle := pointerHandles.Track(data)
269 defer pointerHandles.Untrack(handle)
270
271 ecode := C._go_git_diff_foreach(diff.ptr, 1, intHunks, intLines, handle)
268272 if ecode < 0 {
269273 return data.Error
270274 }
272276 }
273277
274278 //export diffForEachFileCb
275 func diffForEachFileCb(delta *C.git_diff_delta, progress C.float, payload unsafe.Pointer) int {
276 data := (*diffForEachData)(payload)
279 func diffForEachFileCb(delta *C.git_diff_delta, progress C.float, handle unsafe.Pointer) int {
280 payload := pointerHandles.Get(handle)
281 data, ok := payload.(*diffForEachData)
282 if !ok {
283 panic("could not retrieve data for handle")
284 }
277285
278286 data.HunkCallback = nil
279287 if data.FileCallback != nil {
291299 type DiffForEachHunkCallback func(DiffHunk) (DiffForEachLineCallback, error)
292300
293301 //export diffForEachHunkCb
294 func diffForEachHunkCb(delta *C.git_diff_delta, hunk *C.git_diff_hunk, payload unsafe.Pointer) int {
295 data := (*diffForEachData)(payload)
302 func diffForEachHunkCb(delta *C.git_diff_delta, hunk *C.git_diff_hunk, handle unsafe.Pointer) int {
303 payload := pointerHandles.Get(handle)
304 data, ok := payload.(*diffForEachData)
305 if !ok {
306 panic("could not retrieve data for handle")
307 }
296308
297309 data.LineCallback = nil
298310 if data.HunkCallback != nil {
310322 type DiffForEachLineCallback func(DiffLine) error
311323
312324 //export diffForEachLineCb
313 func diffForEachLineCb(delta *C.git_diff_delta, hunk *C.git_diff_hunk, line *C.git_diff_line, payload unsafe.Pointer) int {
314
315 data := (*diffForEachData)(payload)
325 func diffForEachLineCb(delta *C.git_diff_delta, hunk *C.git_diff_hunk, line *C.git_diff_line, handle unsafe.Pointer) int {
326 payload := pointerHandles.Get(handle)
327 data, ok := payload.(*diffForEachData)
328 if !ok {
329 panic("could not retrieve data for handle")
330 }
316331
317332 err := data.LineCallback(diffLineFromC(delta, hunk, line))
318333 if err != nil {
478493 }
479494
480495 //export diffNotifyCb
481 func diffNotifyCb(_diff_so_far unsafe.Pointer, delta_to_add *C.git_diff_delta, matched_pathspec *C.char, payload unsafe.Pointer) int {
496 func diffNotifyCb(_diff_so_far unsafe.Pointer, delta_to_add *C.git_diff_delta, matched_pathspec *C.char, handle unsafe.Pointer) int {
482497 diff_so_far := (*C.git_diff)(_diff_so_far)
483 data := (*diffNotifyData)(payload)
498
499 payload := pointerHandles.Get(handle)
500 data, ok := payload.(*diffNotifyData)
501 if !ok {
502 panic("could not retrieve data for handle")
503 }
504
484505 if data != nil {
485506 if data.Diff == nil {
486507 data.Diff = newDiffFromC(diff_so_far)
506527 notifyData = &diffNotifyData{
507528 Callback: opts.NotifyCallback,
508529 }
530
509531 if opts.Pathspec != nil {
510532 cpathspec.count = C.size_t(len(opts.Pathspec))
511533 cpathspec.strings = makeCStringsFromStrings(opts.Pathspec)
526548
527549 if opts.NotifyCallback != nil {
528550 C._go_git_setup_diff_notify_callbacks(copts)
529 copts.notify_payload = unsafe.Pointer(notifyData)
551 copts.notify_payload = pointerHandles.Track(notifyData)
530552 }
531553 }
532554 return
538560 freeStrarray(&cpathspec)
539561 C.free(unsafe.Pointer(copts.old_prefix))
540562 C.free(unsafe.Pointer(copts.new_prefix))
563 if copts.notify_payload != nil {
564 pointerHandles.Untrack(copts.notify_payload)
565 }
541566 }
542567 }
543568
8686 ErrPassthrough ErrorCode = C.GIT_PASSTHROUGH
8787 // Signals end of iteration with iterator
8888 ErrIterOver ErrorCode = C.GIT_ITEROVER
89 // Authentication failed
90 ErrAuth ErrorCode = C.GIT_EAUTH
8991 )
9092
9193 var (
9294 ErrInvalid = errors.New("Invalid state for operation")
9395 )
9496
97 var pointerHandles *HandleList
98
9599 func init() {
100 pointerHandles = NewHandleList()
101
96102 C.git_libgit2_init()
97103
98104 // This is not something we should be doing, as we may be
0 package git
1
2 import (
3 "fmt"
4 "sync"
5 "unsafe"
6 )
7
8 type HandleList struct {
9 sync.RWMutex
10 // stores the Go pointers
11 handles []interface{}
12 // indicates which indices are in use
13 set map[int]bool
14 }
15
16 func NewHandleList() *HandleList {
17 return &HandleList{
18 handles: make([]interface{}, 5),
19 set: make(map[int]bool),
20 }
21 }
22
23 // findUnusedSlot finds the smallest-index empty space in our
24 // list. You must only run this function while holding a write lock.
25 func (v *HandleList) findUnusedSlot() int {
26 for i := 1; i < len(v.handles); i++ {
27 isUsed := v.set[i]
28 if !isUsed {
29 return i
30 }
31 }
32
33 // reaching here means we've run out of entries so append and
34 // return the new index, which is equal to the old length.
35 slot := len(v.handles)
36 v.handles = append(v.handles, nil)
37
38 return slot
39 }
40
41 // Track adds the given pointer to the list of pointers to track and
42 // returns a pointer value which can be passed to C as an opaque
43 // pointer.
44 func (v *HandleList) Track(pointer interface{}) unsafe.Pointer {
45 v.Lock()
46
47 slot := v.findUnusedSlot()
48 v.handles[slot] = pointer
49 v.set[slot] = true
50
51 v.Unlock()
52
53 return unsafe.Pointer(&slot)
54 }
55
56 // Untrack stops tracking the pointer given by the handle
57 func (v *HandleList) Untrack(handle unsafe.Pointer) {
58 slot := *(*int)(handle)
59
60 v.Lock()
61
62 v.handles[slot] = nil
63 delete(v.set, slot)
64
65 v.Unlock()
66 }
67
68 // Get retrieves the pointer from the given handle
69 func (v *HandleList) Get(handle unsafe.Pointer) interface{} {
70 slot := *(*int)(handle)
71
72 v.RLock()
73
74 if _, ok := v.set[slot]; !ok {
75 panic(fmt.Sprintf("invalid pointer handle: %p", handle))
76 }
77
78 ptr := v.handles[slot]
79
80 v.RUnlock()
81
82 return ptr
83 }
161161 runtime.LockOSThread()
162162 defer runtime.UnlockOSThread()
163163
164 var cb *IndexMatchedPathCallback
164 var handle unsafe.Pointer
165165 if callback != nil {
166 cb = &callback
166 handle = pointerHandles.Track(callback)
167 defer pointerHandles.Untrack(handle)
167168 }
168169
169170 ret := C._go_git_index_add_all(
170171 v.ptr,
171172 &cpathspecs,
172173 C.uint(flags),
173 unsafe.Pointer(cb),
174 handle,
174175 )
175176 if ret < 0 {
176177 return MakeGitError(ret)
187188 runtime.LockOSThread()
188189 defer runtime.UnlockOSThread()
189190
190 var cb *IndexMatchedPathCallback
191 var handle unsafe.Pointer
191192 if callback != nil {
192 cb = &callback
193 handle = pointerHandles.Track(callback)
194 defer pointerHandles.Untrack(handle)
193195 }
194196
195197 ret := C._go_git_index_update_all(
196198 v.ptr,
197199 &cpathspecs,
198 unsafe.Pointer(cb),
200 handle,
199201 )
200202 if ret < 0 {
201203 return MakeGitError(ret)
212214 runtime.LockOSThread()
213215 defer runtime.UnlockOSThread()
214216
215 var cb *IndexMatchedPathCallback
217 var handle unsafe.Pointer
216218 if callback != nil {
217 cb = &callback
219 handle = pointerHandles.Track(callback)
220 defer pointerHandles.Untrack(handle)
218221 }
219222
220223 ret := C._go_git_index_remove_all(
221224 v.ptr,
222225 &cpathspecs,
223 unsafe.Pointer(cb),
226 handle,
224227 )
225228 if ret < 0 {
226229 return MakeGitError(ret)
230233
231234 //export indexMatchedPathCallback
232235 func indexMatchedPathCallback(cPath, cMatchedPathspec *C.char, payload unsafe.Pointer) int {
233 callback := (*IndexMatchedPathCallback)(payload)
234 return (*callback)(C.GoString(cPath), C.GoString(cMatchedPathspec))
236 if callback, ok := pointerHandles.Get(payload).(IndexMatchedPathCallback); ok {
237 return callback(C.GoString(cPath), C.GoString(cMatchedPathspec))
238 } else {
239 panic("invalid matched path callback")
240 }
235241 }
236242
237243 func (v *Index) RemoveByPath(path string) error {
187187 // The failure happens at wherever we were called, not here
188188 _, file, line, ok := runtime.Caller(1)
189189 if !ok {
190 t.Fatal()
190 t.Fatalf("Unable to get caller")
191191 }
192
193192 t.Fatalf("Fail at %v:%v; %v", file, line, err)
194193 }
9797 }
9898
9999 //export odbForEachCb
100 func odbForEachCb(id *C.git_oid, payload unsafe.Pointer) int {
101 data := (*foreachData)(payload)
100 func odbForEachCb(id *C.git_oid, handle unsafe.Pointer) int {
101 data, ok := pointerHandles.Get(handle).(*foreachData)
102
103 if !ok {
104 panic("could not retrieve handle")
105 }
102106
103107 err := data.callback(newOidFromC(id))
104108 if err != nil {
118122 runtime.LockOSThread()
119123 defer runtime.UnlockOSThread()
120124
121 ret := C._go_git_odb_foreach(v.ptr, unsafe.Pointer(&data))
125 handle := pointerHandles.Track(&data)
126 defer pointerHandles.Untrack(handle)
127
128 ret := C._go_git_odb_foreach(v.ptr, handle)
122129 if ret == C.GIT_EUSER {
123130 return data.err
124131 } else if ret < 0 {
8080
8181 checkFatal(t, err)
8282 if count != expect {
83 t.Fatalf("Expected %v objects, got %v")
83 t.Fatalf("Expected %v objects, got %v", expect, count)
8484 }
8585
8686 expect = 1
109109 }
110110
111111 //export packbuilderForEachCb
112 func packbuilderForEachCb(buf unsafe.Pointer, size C.size_t, payload unsafe.Pointer) int {
113 data := (*packbuilderCbData)(payload)
112 func packbuilderForEachCb(buf unsafe.Pointer, size C.size_t, handle unsafe.Pointer) int {
113 payload := pointerHandles.Get(handle)
114 data, ok := payload.(*packbuilderCbData)
115 if !ok {
116 panic("could not get packbuilder CB data")
117 }
118
114119 slice := C.GoBytes(buf, C.int(size))
115120
116121 err := data.callback(slice)
129134 callback: callback,
130135 err: nil,
131136 }
137 handle := pointerHandles.Track(&data)
138 defer pointerHandles.Untrack(handle)
132139
133140 runtime.LockOSThread()
134141 defer runtime.UnlockOSThread()
135142
136 err := C._go_git_packbuilder_foreach(pb.ptr, unsafe.Pointer(&data))
143 err := C._go_git_packbuilder_foreach(pb.ptr, handle)
137144 if err == C.GIT_EUSER {
138145 return data.err
139146 }
198198 // The failure happens at wherever we were called, not here
199199 _, file, line, ok := runtime.Caller(1)
200200 if !ok {
201 t.Fatal()
202 }
203
201 t.Fatalf("Unable to get caller")
202 }
204203 t.Fatalf("Wrong ref type at %v:%v; have %v, expected %v", file, line, ref.Type(), kind)
205204 }
128128 return
129129 }
130130 C._go_git_setup_callbacks(ptr)
131 ptr.payload = unsafe.Pointer(callbacks)
131 ptr.payload = pointerHandles.Track(callbacks)
132132 }
133133
134134 //export sidebandProgressCallback
135135 func sidebandProgressCallback(_str *C.char, _len C.int, data unsafe.Pointer) int {
136 callbacks := (*RemoteCallbacks)(data)
136 callbacks := pointerHandles.Get(data).(*RemoteCallbacks)
137137 if callbacks.SidebandProgressCallback == nil {
138138 return 0
139139 }
143143
144144 //export completionCallback
145145 func completionCallback(completion_type C.git_remote_completion_type, data unsafe.Pointer) int {
146 callbacks := (*RemoteCallbacks)(data)
146 callbacks := pointerHandles.Get(data).(*RemoteCallbacks)
147147 if callbacks.CompletionCallback == nil {
148148 return 0
149149 }
152152
153153 //export credentialsCallback
154154 func credentialsCallback(_cred **C.git_cred, _url *C.char, _username_from_url *C.char, allowed_types uint, data unsafe.Pointer) int {
155 callbacks := (*RemoteCallbacks)(data)
155 callbacks, _ := pointerHandles.Get(data).(*RemoteCallbacks)
156156 if callbacks.CredentialsCallback == nil {
157157 return 0
158158 }
165165
166166 //export transferProgressCallback
167167 func transferProgressCallback(stats *C.git_transfer_progress, data unsafe.Pointer) int {
168 callbacks := (*RemoteCallbacks)(data)
168 callbacks, _ := pointerHandles.Get(data).(*RemoteCallbacks)
169169 if callbacks.TransferProgressCallback == nil {
170170 return 0
171171 }
174174
175175 //export updateTipsCallback
176176 func updateTipsCallback(_refname *C.char, _a *C.git_oid, _b *C.git_oid, data unsafe.Pointer) int {
177 callbacks := (*RemoteCallbacks)(data)
177 callbacks, _ := pointerHandles.Get(data).(*RemoteCallbacks)
178178 if callbacks.UpdateTipsCallback == nil {
179179 return 0
180180 }
186186
187187 //export certificateCheckCallback
188188 func certificateCheckCallback(_cert *C.git_cert, _valid C.int, _host *C.char, data unsafe.Pointer) int {
189 callbacks := (*RemoteCallbacks)(data)
189 callbacks, _ := pointerHandles.Get(data).(*RemoteCallbacks)
190190 // if there's no callback set, we need to make sure we fail if the library didn't consider this cert valid
191191 if callbacks.CertificateCheckCallback == nil {
192192 if _valid == 1 {
227227
228228 //export packProgressCallback
229229 func packProgressCallback(stage C.int, current, total C.uint, data unsafe.Pointer) int {
230 callbacks := (*RemoteCallbacks)(data)
230 callbacks, _ := pointerHandles.Get(data).(*RemoteCallbacks)
231231
232232 if callbacks.PackProgressCallback == nil {
233233 return 0
238238
239239 //export pushTransferProgressCallback
240240 func pushTransferProgressCallback(current, total C.uint, bytes C.size_t, data unsafe.Pointer) int {
241 callbacks := (*RemoteCallbacks)(data)
241 callbacks, _ := pointerHandles.Get(data).(*RemoteCallbacks)
242242 if callbacks.PushTransferProgressCallback == nil {
243243 return 0
244244 }
248248
249249 //export pushUpdateReferenceCallback
250250 func pushUpdateReferenceCallback(refname, status *C.char, data unsafe.Pointer) int {
251 callbacks := (*RemoteCallbacks)(data)
251 callbacks, _ := pointerHandles.Get(data).(*RemoteCallbacks)
252252
253253 if callbacks.PushUpdateReferenceCallback == nil {
254254 return 0
285285
286286 func (r *Remote) Free() {
287287 runtime.SetFinalizer(r, nil)
288
289 callbacks := C.git_remote_get_callbacks(r.ptr)
290 if callbacks != nil && callbacks.payload != nil {
291 pointerHandles.Untrack(callbacks.payload)
292 }
293
288294 C.git_remote_free(r.ptr)
289295 }
290296
9696 type SubmoduleCbk func(sub *Submodule, name string) int
9797
9898 //export SubmoduleVisitor
99 func SubmoduleVisitor(csub unsafe.Pointer, name *C.char, cfct unsafe.Pointer) C.int {
99 func SubmoduleVisitor(csub unsafe.Pointer, name *C.char, handle unsafe.Pointer) C.int {
100100 sub := &Submodule{(*C.git_submodule)(csub)}
101 fct := *(*SubmoduleCbk)(cfct)
102 return (C.int)(fct(sub, C.GoString(name)))
101
102 if callback, ok := pointerHandles.Get(handle).(SubmoduleCbk); ok {
103 return (C.int)(callback(sub, C.GoString(name)))
104 } else {
105 panic("invalid submodule visitor callback")
106 }
103107 }
104108
105109 func (repo *Repository) ForeachSubmodule(cbk SubmoduleCbk) error {
106110 runtime.LockOSThread()
107111 defer runtime.UnlockOSThread()
108112
109 ret := C._go_git_visit_submodule(repo.ptr, unsafe.Pointer(&cbk))
113 handle := pointerHandles.Track(cbk)
114 defer pointerHandles.Untrack(handle)
115
116 ret := C._go_git_visit_submodule(repo.ptr, handle)
110117 if ret < 0 {
111118 return MakeGitError(ret)
112119 }
2020 checkFatal(t, err)
2121
2222 if i != 1 {
23 t.Fatalf("expected one submodule found but got %i", i)
23 t.Fatalf("expected one submodule found but got %d", i)
2424 }
2525 }
8989 type TreeWalkCallback func(string, *TreeEntry) int
9090
9191 //export CallbackGitTreeWalk
92 func CallbackGitTreeWalk(_root unsafe.Pointer, _entry unsafe.Pointer, ptr unsafe.Pointer) C.int {
93 root := C.GoString((*C.char)(_root))
92 func CallbackGitTreeWalk(_root *C.char, _entry unsafe.Pointer, ptr unsafe.Pointer) C.int {
93 root := C.GoString(_root)
9494 entry := (*C.git_tree_entry)(_entry)
95 callback := *(*TreeWalkCallback)(ptr)
9695
97 return C.int(callback(root, newTreeEntry(entry)))
96 if callback, ok := pointerHandles.Get(ptr).(TreeWalkCallback); ok {
97 return C.int(callback(root, newTreeEntry(entry)))
98 } else {
99 panic("invalid treewalk callback")
100 }
98101 }
99102
100103 func (t Tree) Walk(callback TreeWalkCallback) error {
101104 runtime.LockOSThread()
102105 defer runtime.UnlockOSThread()
103106
107 ptr := pointerHandles.Track(callback)
108 defer pointerHandles.Untrack(ptr)
109
104110 err := C._go_git_treewalk(
105111 t.cast_ptr,
106112 C.GIT_TREEWALK_PRE,
107 unsafe.Pointer(&callback),
113 ptr,
108114 )
109115
110116 if err < 0 {