Imported Upstream version 0.0~git20150623
Maximiliano Curia
8 years ago
59 | 59 | } |
60 | 60 | |
61 | 61 | //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 | ||
64 | 69 | goBuf, err := data.Callback(int(maxLen)) |
65 | 70 | if err == io.EOF { |
66 | 71 | return 0 |
82 | 87 | defer C.free(unsafe.Pointer(chintPath)) |
83 | 88 | } |
84 | 89 | oid := C.git_oid{} |
90 | ||
85 | 91 | 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) | |
87 | 96 | if payload.Error != nil { |
88 | 97 | return nil, payload.Error |
89 | 98 | } |
91 | 91 | |
92 | 92 | func (repo *Repository) CreateBranch(branchName string, target *Commit, force bool, signature *Signature, msg string) (*Branch, error) { |
93 | 93 | |
94 | ref := new(Reference) | |
94 | var ptr *C.git_reference | |
95 | 95 | cBranchName := C.CString(branchName) |
96 | 96 | cForce := cbool(force) |
97 | 97 | |
112 | 112 | runtime.LockOSThread() |
113 | 113 | defer runtime.UnlockOSThread() |
114 | 114 | |
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 | |
120 | 120 | } |
121 | 121 | |
122 | 122 | func (b *Branch) Delete() error { |
27 | 27 | cpath := C.CString(path) |
28 | 28 | defer C.free(unsafe.Pointer(cpath)) |
29 | 29 | |
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) | |
33 | 32 | |
34 | 33 | if len(options.CheckoutBranch) != 0 { |
35 | 34 | copts.checkout_branch = C.CString(options.CheckoutBranch) |
36 | defer C.free(unsafe.Pointer(copts.checkout_branch)) | |
37 | 35 | } |
38 | 36 | |
39 | 37 | runtime.LockOSThread() |
40 | 38 | 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 | ||
42 | 44 | if ret < 0 { |
43 | 45 | return nil, MakeGitError(ret) |
44 | 46 | } |
264 | 264 | data := &diffForEachData{ |
265 | 265 | FileCallback: cbFile, |
266 | 266 | } |
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) | |
268 | 272 | if ecode < 0 { |
269 | 273 | return data.Error |
270 | 274 | } |
272 | 276 | } |
273 | 277 | |
274 | 278 | //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 | } | |
277 | 285 | |
278 | 286 | data.HunkCallback = nil |
279 | 287 | if data.FileCallback != nil { |
291 | 299 | type DiffForEachHunkCallback func(DiffHunk) (DiffForEachLineCallback, error) |
292 | 300 | |
293 | 301 | //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 | } | |
296 | 308 | |
297 | 309 | data.LineCallback = nil |
298 | 310 | if data.HunkCallback != nil { |
310 | 322 | type DiffForEachLineCallback func(DiffLine) error |
311 | 323 | |
312 | 324 | //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 | } | |
316 | 331 | |
317 | 332 | err := data.LineCallback(diffLineFromC(delta, hunk, line)) |
318 | 333 | if err != nil { |
478 | 493 | } |
479 | 494 | |
480 | 495 | //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 { | |
482 | 497 | 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 | ||
484 | 505 | if data != nil { |
485 | 506 | if data.Diff == nil { |
486 | 507 | data.Diff = newDiffFromC(diff_so_far) |
506 | 527 | notifyData = &diffNotifyData{ |
507 | 528 | Callback: opts.NotifyCallback, |
508 | 529 | } |
530 | ||
509 | 531 | if opts.Pathspec != nil { |
510 | 532 | cpathspec.count = C.size_t(len(opts.Pathspec)) |
511 | 533 | cpathspec.strings = makeCStringsFromStrings(opts.Pathspec) |
526 | 548 | |
527 | 549 | if opts.NotifyCallback != nil { |
528 | 550 | C._go_git_setup_diff_notify_callbacks(copts) |
529 | copts.notify_payload = unsafe.Pointer(notifyData) | |
551 | copts.notify_payload = pointerHandles.Track(notifyData) | |
530 | 552 | } |
531 | 553 | } |
532 | 554 | return |
538 | 560 | freeStrarray(&cpathspec) |
539 | 561 | C.free(unsafe.Pointer(copts.old_prefix)) |
540 | 562 | C.free(unsafe.Pointer(copts.new_prefix)) |
563 | if copts.notify_payload != nil { | |
564 | pointerHandles.Untrack(copts.notify_payload) | |
565 | } | |
541 | 566 | } |
542 | 567 | } |
543 | 568 |
86 | 86 | ErrPassthrough ErrorCode = C.GIT_PASSTHROUGH |
87 | 87 | // Signals end of iteration with iterator |
88 | 88 | ErrIterOver ErrorCode = C.GIT_ITEROVER |
89 | // Authentication failed | |
90 | ErrAuth ErrorCode = C.GIT_EAUTH | |
89 | 91 | ) |
90 | 92 | |
91 | 93 | var ( |
92 | 94 | ErrInvalid = errors.New("Invalid state for operation") |
93 | 95 | ) |
94 | 96 | |
97 | var pointerHandles *HandleList | |
98 | ||
95 | 99 | func init() { |
100 | pointerHandles = NewHandleList() | |
101 | ||
96 | 102 | C.git_libgit2_init() |
97 | 103 | |
98 | 104 | // 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 | } |
161 | 161 | runtime.LockOSThread() |
162 | 162 | defer runtime.UnlockOSThread() |
163 | 163 | |
164 | var cb *IndexMatchedPathCallback | |
164 | var handle unsafe.Pointer | |
165 | 165 | if callback != nil { |
166 | cb = &callback | |
166 | handle = pointerHandles.Track(callback) | |
167 | defer pointerHandles.Untrack(handle) | |
167 | 168 | } |
168 | 169 | |
169 | 170 | ret := C._go_git_index_add_all( |
170 | 171 | v.ptr, |
171 | 172 | &cpathspecs, |
172 | 173 | C.uint(flags), |
173 | unsafe.Pointer(cb), | |
174 | handle, | |
174 | 175 | ) |
175 | 176 | if ret < 0 { |
176 | 177 | return MakeGitError(ret) |
187 | 188 | runtime.LockOSThread() |
188 | 189 | defer runtime.UnlockOSThread() |
189 | 190 | |
190 | var cb *IndexMatchedPathCallback | |
191 | var handle unsafe.Pointer | |
191 | 192 | if callback != nil { |
192 | cb = &callback | |
193 | handle = pointerHandles.Track(callback) | |
194 | defer pointerHandles.Untrack(handle) | |
193 | 195 | } |
194 | 196 | |
195 | 197 | ret := C._go_git_index_update_all( |
196 | 198 | v.ptr, |
197 | 199 | &cpathspecs, |
198 | unsafe.Pointer(cb), | |
200 | handle, | |
199 | 201 | ) |
200 | 202 | if ret < 0 { |
201 | 203 | return MakeGitError(ret) |
212 | 214 | runtime.LockOSThread() |
213 | 215 | defer runtime.UnlockOSThread() |
214 | 216 | |
215 | var cb *IndexMatchedPathCallback | |
217 | var handle unsafe.Pointer | |
216 | 218 | if callback != nil { |
217 | cb = &callback | |
219 | handle = pointerHandles.Track(callback) | |
220 | defer pointerHandles.Untrack(handle) | |
218 | 221 | } |
219 | 222 | |
220 | 223 | ret := C._go_git_index_remove_all( |
221 | 224 | v.ptr, |
222 | 225 | &cpathspecs, |
223 | unsafe.Pointer(cb), | |
226 | handle, | |
224 | 227 | ) |
225 | 228 | if ret < 0 { |
226 | 229 | return MakeGitError(ret) |
230 | 233 | |
231 | 234 | //export indexMatchedPathCallback |
232 | 235 | 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 | } | |
235 | 241 | } |
236 | 242 | |
237 | 243 | func (v *Index) RemoveByPath(path string) error { |
187 | 187 | // The failure happens at wherever we were called, not here |
188 | 188 | _, file, line, ok := runtime.Caller(1) |
189 | 189 | if !ok { |
190 | t.Fatal() | |
190 | t.Fatalf("Unable to get caller") | |
191 | 191 | } |
192 | ||
193 | 192 | t.Fatalf("Fail at %v:%v; %v", file, line, err) |
194 | 193 | } |
97 | 97 | } |
98 | 98 | |
99 | 99 | //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 | } | |
102 | 106 | |
103 | 107 | err := data.callback(newOidFromC(id)) |
104 | 108 | if err != nil { |
118 | 122 | runtime.LockOSThread() |
119 | 123 | defer runtime.UnlockOSThread() |
120 | 124 | |
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) | |
122 | 129 | if ret == C.GIT_EUSER { |
123 | 130 | return data.err |
124 | 131 | } else if ret < 0 { |
80 | 80 | |
81 | 81 | checkFatal(t, err) |
82 | 82 | if count != expect { |
83 | t.Fatalf("Expected %v objects, got %v") | |
83 | t.Fatalf("Expected %v objects, got %v", expect, count) | |
84 | 84 | } |
85 | 85 | |
86 | 86 | expect = 1 |
109 | 109 | } |
110 | 110 | |
111 | 111 | //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 | ||
114 | 119 | slice := C.GoBytes(buf, C.int(size)) |
115 | 120 | |
116 | 121 | err := data.callback(slice) |
129 | 134 | callback: callback, |
130 | 135 | err: nil, |
131 | 136 | } |
137 | handle := pointerHandles.Track(&data) | |
138 | defer pointerHandles.Untrack(handle) | |
132 | 139 | |
133 | 140 | runtime.LockOSThread() |
134 | 141 | defer runtime.UnlockOSThread() |
135 | 142 | |
136 | err := C._go_git_packbuilder_foreach(pb.ptr, unsafe.Pointer(&data)) | |
143 | err := C._go_git_packbuilder_foreach(pb.ptr, handle) | |
137 | 144 | if err == C.GIT_EUSER { |
138 | 145 | return data.err |
139 | 146 | } |
198 | 198 | // The failure happens at wherever we were called, not here |
199 | 199 | _, file, line, ok := runtime.Caller(1) |
200 | 200 | if !ok { |
201 | t.Fatal() | |
202 | } | |
203 | ||
201 | t.Fatalf("Unable to get caller") | |
202 | } | |
204 | 203 | t.Fatalf("Wrong ref type at %v:%v; have %v, expected %v", file, line, ref.Type(), kind) |
205 | 204 | } |
128 | 128 | return |
129 | 129 | } |
130 | 130 | C._go_git_setup_callbacks(ptr) |
131 | ptr.payload = unsafe.Pointer(callbacks) | |
131 | ptr.payload = pointerHandles.Track(callbacks) | |
132 | 132 | } |
133 | 133 | |
134 | 134 | //export sidebandProgressCallback |
135 | 135 | func sidebandProgressCallback(_str *C.char, _len C.int, data unsafe.Pointer) int { |
136 | callbacks := (*RemoteCallbacks)(data) | |
136 | callbacks := pointerHandles.Get(data).(*RemoteCallbacks) | |
137 | 137 | if callbacks.SidebandProgressCallback == nil { |
138 | 138 | return 0 |
139 | 139 | } |
143 | 143 | |
144 | 144 | //export completionCallback |
145 | 145 | func completionCallback(completion_type C.git_remote_completion_type, data unsafe.Pointer) int { |
146 | callbacks := (*RemoteCallbacks)(data) | |
146 | callbacks := pointerHandles.Get(data).(*RemoteCallbacks) | |
147 | 147 | if callbacks.CompletionCallback == nil { |
148 | 148 | return 0 |
149 | 149 | } |
152 | 152 | |
153 | 153 | //export credentialsCallback |
154 | 154 | 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) | |
156 | 156 | if callbacks.CredentialsCallback == nil { |
157 | 157 | return 0 |
158 | 158 | } |
165 | 165 | |
166 | 166 | //export transferProgressCallback |
167 | 167 | func transferProgressCallback(stats *C.git_transfer_progress, data unsafe.Pointer) int { |
168 | callbacks := (*RemoteCallbacks)(data) | |
168 | callbacks, _ := pointerHandles.Get(data).(*RemoteCallbacks) | |
169 | 169 | if callbacks.TransferProgressCallback == nil { |
170 | 170 | return 0 |
171 | 171 | } |
174 | 174 | |
175 | 175 | //export updateTipsCallback |
176 | 176 | 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) | |
178 | 178 | if callbacks.UpdateTipsCallback == nil { |
179 | 179 | return 0 |
180 | 180 | } |
186 | 186 | |
187 | 187 | //export certificateCheckCallback |
188 | 188 | 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) | |
190 | 190 | // if there's no callback set, we need to make sure we fail if the library didn't consider this cert valid |
191 | 191 | if callbacks.CertificateCheckCallback == nil { |
192 | 192 | if _valid == 1 { |
227 | 227 | |
228 | 228 | //export packProgressCallback |
229 | 229 | func packProgressCallback(stage C.int, current, total C.uint, data unsafe.Pointer) int { |
230 | callbacks := (*RemoteCallbacks)(data) | |
230 | callbacks, _ := pointerHandles.Get(data).(*RemoteCallbacks) | |
231 | 231 | |
232 | 232 | if callbacks.PackProgressCallback == nil { |
233 | 233 | return 0 |
238 | 238 | |
239 | 239 | //export pushTransferProgressCallback |
240 | 240 | func pushTransferProgressCallback(current, total C.uint, bytes C.size_t, data unsafe.Pointer) int { |
241 | callbacks := (*RemoteCallbacks)(data) | |
241 | callbacks, _ := pointerHandles.Get(data).(*RemoteCallbacks) | |
242 | 242 | if callbacks.PushTransferProgressCallback == nil { |
243 | 243 | return 0 |
244 | 244 | } |
248 | 248 | |
249 | 249 | //export pushUpdateReferenceCallback |
250 | 250 | func pushUpdateReferenceCallback(refname, status *C.char, data unsafe.Pointer) int { |
251 | callbacks := (*RemoteCallbacks)(data) | |
251 | callbacks, _ := pointerHandles.Get(data).(*RemoteCallbacks) | |
252 | 252 | |
253 | 253 | if callbacks.PushUpdateReferenceCallback == nil { |
254 | 254 | return 0 |
285 | 285 | |
286 | 286 | func (r *Remote) Free() { |
287 | 287 | 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 | ||
288 | 294 | C.git_remote_free(r.ptr) |
289 | 295 | } |
290 | 296 |
96 | 96 | type SubmoduleCbk func(sub *Submodule, name string) int |
97 | 97 | |
98 | 98 | //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 { | |
100 | 100 | 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 | } | |
103 | 107 | } |
104 | 108 | |
105 | 109 | func (repo *Repository) ForeachSubmodule(cbk SubmoduleCbk) error { |
106 | 110 | runtime.LockOSThread() |
107 | 111 | defer runtime.UnlockOSThread() |
108 | 112 | |
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) | |
110 | 117 | if ret < 0 { |
111 | 118 | return MakeGitError(ret) |
112 | 119 | } |
20 | 20 | checkFatal(t, err) |
21 | 21 | |
22 | 22 | 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) | |
24 | 24 | } |
25 | 25 | } |
89 | 89 | type TreeWalkCallback func(string, *TreeEntry) int |
90 | 90 | |
91 | 91 | //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) | |
94 | 94 | entry := (*C.git_tree_entry)(_entry) |
95 | callback := *(*TreeWalkCallback)(ptr) | |
96 | 95 | |
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 | } | |
98 | 101 | } |
99 | 102 | |
100 | 103 | func (t Tree) Walk(callback TreeWalkCallback) error { |
101 | 104 | runtime.LockOSThread() |
102 | 105 | defer runtime.UnlockOSThread() |
103 | 106 | |
107 | ptr := pointerHandles.Track(callback) | |
108 | defer pointerHandles.Untrack(ptr) | |
109 | ||
104 | 110 | err := C._go_git_treewalk( |
105 | 111 | t.cast_ptr, |
106 | 112 | C.GIT_TREEWALK_PRE, |
107 | unsafe.Pointer(&callback), | |
113 | ptr, | |
108 | 114 | ) |
109 | 115 | |
110 | 116 | if err < 0 { |