From 794dbe7b9cb5475e6c98d5e51abe6b10a7c7151c Mon Sep 17 00:00:00 2001 From: Matthew Duggan <mgithub@guarana.org> Date: Mon, 18 Aug 2014 18:22:45 +0900 Subject: [PATCH] set callbacks just before fetch, clear them after (fixes #403). --- pygit2/decl.h | 2 ++ pygit2/remote.py | 44 ++++++++++++++++++++++++++------------------ 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/pygit2/decl.h b/pygit2/decl.h index 5573ecd..0676b67 100644 --- a/pygit2/decl.h +++ b/pygit2/decl.h @@ -12,6 +12,7 @@ typedef ... git_index_conflict_iterator; #define GIT_OID_RAWSZ ... #define GIT_PATH_MAX ... +#define GIT_REMOTE_CALLBACKS_VERSION ... typedef struct git_oid { unsigned char id[20]; @@ -136,6 +137,7 @@ int git_remote_add_push(git_remote *remote, const char *refspec); int git_remote_add_fetch(git_remote *remote, const char *refspec); int git_remote_save(const git_remote *remote); int git_remote_set_callbacks(git_remote *remote, const git_remote_callbacks *callbacks); +int git_remote_init_callbacks(git_remote_callbacks *opts, unsigned int version); size_t git_remote_refspec_count(git_remote *remote); const git_refspec * git_remote_get_refspec(git_remote *remote, size_t n); diff --git a/pygit2/remote.py b/pygit2/remote.py index b2fdec2..dfeb4d7 100644 --- a/pygit2/remote.py +++ b/pygit2/remote.py @@ -127,20 +127,6 @@ class Remote(object): self._remote = ptr self._stored_exception = None - # Build the callback structure - callbacks = ffi.new('git_remote_callbacks *') - callbacks.version = 1 - callbacks.sideband_progress = self._sideband_progress_cb - callbacks.transfer_progress = self._transfer_progress_cb - callbacks.update_tips = self._update_tips_cb - callbacks.credentials = self._credentials_cb - # We need to make sure that this handle stays alive - self._self_handle = ffi.new_handle(self) - callbacks.payload = self._self_handle - - err = C.git_remote_set_callbacks(self._remote, callbacks) - check_error(err) - def __del__(self): C.git_remote_free(self._remote) @@ -205,17 +191,39 @@ class Remote(object): Perform a fetch against this remote. """ + defaultcallbacks = ffi.new('git_remote_callbacks *') + err = C.git_remote_init_callbacks(defaultcallbacks, + C.GIT_REMOTE_CALLBACKS_VERSION) + + # Build the callback structure + callbacks = ffi.new('git_remote_callbacks *') + callbacks.version = 1 + callbacks.sideband_progress = self._sideband_progress_cb + callbacks.transfer_progress = self._transfer_progress_cb + callbacks.update_tips = self._update_tips_cb + callbacks.credentials = self._credentials_cb + callbacks.payload = ffi.new_handle(self) + + err = C.git_remote_set_callbacks(self._remote, callbacks) + check_error(err) + if signature: ptr = signature._pointer[:] else: ptr = ffi.NULL self._stored_exception = None - err = C.git_remote_fetch(self._remote, ptr, to_bytes(message)) - if self._stored_exception: - raise self._stored_exception - check_error(err) + try: + err = C.git_remote_fetch(self._remote, ptr, to_bytes(message)) + if self._stored_exception: + raise self._stored_exception + + check_error(err) + finally: + # Even on error, clear stored callbacks and reset to default + err = C.git_remote_set_callbacks(self._remote, defaultcallbacks) + check_error(err) return TransferProgress(C.git_remote_stats(self._remote))