From b3aaa7a7c887006d38b7262b73575d40f51beca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sat, 21 Jul 2012 17:52:51 +0200 Subject: [PATCH] Add a struct for network callbacks Currently only update_tips is used, but it prepares the way for progress output during download. --- examples/network/fetch.c | 11 +++++++++-- include/git2/remote.h | 35 ++++++++++++++++++++++++++++++++++- include/git2/types.h | 1 + src/remote.c | 13 ++++++++++--- src/remote.h | 1 + 5 files changed, 55 insertions(+), 6 deletions(-) diff --git a/examples/network/fetch.c b/examples/network/fetch.c index d2752124d..73bfbddd0 100644 --- a/examples/network/fetch.c +++ b/examples/network/fetch.c @@ -4,6 +4,7 @@ #include #include #include +#include struct dl_data { git_remote *remote; @@ -39,7 +40,7 @@ exit: pthread_exit(&data->ret); } -int update_cb(const char *refname, const git_oid *a, const git_oid *b) +int update_cb(const char *refname, const git_oid *a, const git_oid *b, void *data) { const char *action; char a_str[GIT_OID_HEXSZ+1], b_str[GIT_OID_HEXSZ+1]; @@ -65,6 +66,7 @@ int fetch(git_repository *repo, int argc, char **argv) git_indexer_stats stats; pthread_t worker; struct dl_data data; + git_remote_callbacks callbacks; // Figure out whether it's a named remote or a URL printf("Fetching %s\n", argv[1]); @@ -73,6 +75,11 @@ int fetch(git_repository *repo, int argc, char **argv) return -1; } + // Set up the callbacks (only update_tips for now) + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.update_tips = &update_cb; + git_remote_set_callbacks(remote, &callbacks); + // Set up the information for the background worker thread data.remote = remote; data.bytes = &bytes; @@ -101,7 +108,7 @@ int fetch(git_repository *repo, int argc, char **argv) // right commits. This may be needed even if there was no packfile // to download, which can happen e.g. when the branches have been // changed but all the neede objects are available locally. - if (git_remote_update_tips(remote, update_cb) < 0) + if (git_remote_update_tips(remote) < 0) return -1; git_remote_free(remote); diff --git a/include/git2/remote.h b/include/git2/remote.h index 5c01949d2..dc6642cc5 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -190,7 +190,7 @@ GIT_EXTERN(void) git_remote_free(git_remote *remote); * @param remote the remote to update * @param cb callback to run on each ref update. 'a' is the old value, 'b' is then new value */ -GIT_EXTERN(int) git_remote_update_tips(git_remote *remote, int (*cb)(const char *refname, const git_oid *a, const git_oid *b)); +GIT_EXTERN(int) git_remote_update_tips(git_remote *remote); /** * Return whether a string is a valid remote URL @@ -238,6 +238,39 @@ GIT_EXTERN(int) git_remote_add(git_remote **out, git_repository *repo, const cha GIT_EXTERN(void) git_remote_check_cert(git_remote *remote, int check); +/** + * Argument to the completion callback which tells it which operation + * finished. + */ +typedef enum git_remote_completion_type { + GIT_REMOTE_COMPLETION_DOWNLOAD, + GIT_REMOTE_COMPLETION_INDEXING, + GIT_REMOTE_COMPLETION_ERROR, +} git_remote_completion_type; + +/** + * The callback settings structure + * + * Set the calbacks to be called by the remote. + */ +struct git_remote_callbacks { + int (*progress)(const char *str, void *data); + int (*completion)(git_remote_completion_type type, void *data); + int (*update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data); + void *data; +}; + +/** + * Set the callbacks for a remote + * + * Note that the remote keeps its own copy of the data and you need to + * call this function again if you want to change the callbacks. + * + * @param remote the remote to configure + * @param callbacks a pointer to the user's callback settings + */ +GIT_EXTERN(void) git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks); + /** @} */ GIT_END_DECL #endif diff --git a/include/git2/types.h b/include/git2/types.h index 691903005..acd5a73bc 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -179,6 +179,7 @@ typedef struct git_refspec git_refspec; typedef struct git_remote git_remote; typedef struct git_remote_head git_remote_head; +typedef struct git_remote_callbacks git_remote_callbacks; /** @} */ GIT_END_DECL diff --git a/src/remote.c b/src/remote.c index 00e108a0a..e661fff86 100644 --- a/src/remote.c +++ b/src/remote.c @@ -331,7 +331,7 @@ int git_remote_download(git_remote *remote, git_off_t *bytes, git_indexer_stats return git_fetch_download_pack(remote, bytes, stats); } -int git_remote_update_tips(git_remote *remote, int (*cb)(const char *refname, const git_oid *a, const git_oid *b)) +int git_remote_update_tips(git_remote *remote) { int error = 0; unsigned int i = 0; @@ -381,8 +381,8 @@ int git_remote_update_tips(git_remote *remote, int (*cb)(const char *refname, co git_reference_free(ref); - if (cb != NULL) { - if (cb(refname.ptr, &old, &head->oid) < 0) + if (remote->callbacks.update_tips != NULL) { + if (remote->callbacks.update_tips(refname.ptr, &old, &head->oid, remote->callbacks.data) < 0) goto on_error; } } @@ -525,3 +525,10 @@ void git_remote_check_cert(git_remote *remote, int check) remote->check_cert = check; } + +void git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks) +{ + assert(remote && callbacks); + + memcpy(&remote->callbacks, callbacks, sizeof(git_remote_callbacks)); +} diff --git a/src/remote.h b/src/remote.h index 0949ad434..3360b6249 100644 --- a/src/remote.h +++ b/src/remote.h @@ -19,6 +19,7 @@ struct git_remote { struct git_refspec push; git_transport *transport; git_repository *repo; + git_remote_callbacks callbacks; unsigned int need_pack:1, check_cert; };