Commit 9267ff586f29deb99f41ab6eeb0599917ddd0cec

Ben Straub 2012-11-29T20:01:24

Deploy GIT_REMOTE_CALLBACKS_INIT

diff --git a/examples/network/fetch.c b/examples/network/fetch.c
index e341d2d..8048fd6 100644
--- a/examples/network/fetch.c
+++ b/examples/network/fetch.c
@@ -70,7 +70,7 @@ int fetch(git_repository *repo, int argc, char **argv)
 	const git_transfer_progress *stats;
 	pthread_t worker;
 	struct dl_data data;
-	git_remote_callbacks callbacks;
+	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
 
 	argc = argc;
 	// Figure out whether it's a named remote or a URL
@@ -81,7 +81,6 @@ int fetch(git_repository *repo, int argc, char **argv)
 	}
 
 	// Set up the callbacks (only update_tips for now)
-	memset(&callbacks, 0, sizeof(callbacks));
 	callbacks.update_tips = &update_cb;
 	callbacks.progress = &progress_cb;
 	git_remote_set_callbacks(remote, &callbacks);
diff --git a/include/git2/remote.h b/include/git2/remote.h
index e5b60b9..3e22004 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -356,8 +356,9 @@ struct git_remote_callbacks {
  *
  * @param remote the remote to configure
  * @param callbacks a pointer to the user's callback settings
+ * @return 0 or an error code
  */
-GIT_EXTERN(void) git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks);
+GIT_EXTERN(int) git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks);
 
 /**
  * Get the statistics structure that is filled in by the fetch operation.
diff --git a/src/remote.c b/src/remote.c
index c84911a..d516d07 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -985,10 +985,25 @@ 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)
+static bool callbacks_have_valid_version(git_remote_callbacks *callbacks)
+{
+	if (!callbacks)
+		return true;
+
+	if (callbacks->version > 0 && callbacks->version <= GIT_REMOTE_CALLBACKS_VERSION)
+		return true;
+
+	giterr_set(GITERR_INVALID, "Invalid version %d for git_remote_callbacks", callbacks->version);
+	return false;
+}
+
+int git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks)
 {
 	assert(remote && callbacks);
 
+	if (!callbacks_have_valid_version(callbacks))
+		return -1;
+
 	memcpy(&remote->callbacks, callbacks, sizeof(git_remote_callbacks));
 
 	if (remote->transport && remote->transport->set_callbacks)
@@ -996,6 +1011,8 @@ void git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callback
 			remote->callbacks.progress,
 			NULL,
 			remote->callbacks.payload);
+
+	return 0;
 }
 
 void git_remote_set_cred_acquire_cb(
diff --git a/tests-clar/network/fetch.c b/tests-clar/network/fetch.c
index 26937c6..859479e 100644
--- a/tests-clar/network/fetch.c
+++ b/tests-clar/network/fetch.c
@@ -36,10 +36,9 @@ static void progress(const git_transfer_progress *stats, void *payload)
 static void do_fetch(const char *url, git_remote_autotag_option_t flag, int n)
 {
 	git_remote *remote;
-	git_remote_callbacks callbacks;
+	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
 	size_t bytes_received = 0;
 
-	memset(&callbacks, 0, sizeof(git_remote_callbacks));
 	callbacks.update_tips = update_tips;
 	counter = 0;
 
diff --git a/tests-clar/network/push_util.h b/tests-clar/network/push_util.h
index 2f4dffc..759122a 100644
--- a/tests-clar/network/push_util.h
+++ b/tests-clar/network/push_util.h
@@ -11,7 +11,8 @@ extern const git_oid OID_ZERO;
  * record data in a record_callbacks_data instance.
  * @param data pointer to a record_callbacks_data instance
  */
-#define RECORD_CALLBACKS_INIT(data) { NULL, NULL, record_update_tips_cb, data }
+#define RECORD_CALLBACKS_INIT(data) \
+	{ GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, record_update_tips_cb, data }
 
 typedef struct {
 	char *name;