Merge pull request #834 from carlosmn/network-callbacks Add a struct for network callbacks
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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
diff --git a/examples/network/fetch.c b/examples/network/fetch.c
index d275212..73bfbdd 100644
--- a/examples/network/fetch.c
+++ b/examples/network/fetch.c
@@ -4,6 +4,7 @@
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
+#include <unistd.h>
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 6d4b6cc..7e563f9 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -220,7 +220,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
@@ -268,6 +268,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 6919030..acd5a73 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 c479c19..c2bfb09 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -423,7 +423,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;
@@ -473,8 +473,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;
}
}
@@ -618,3 +618,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 623d40c..5083b99 100644
--- a/src/remote.h
+++ b/src/remote.h
@@ -20,6 +20,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;
};