From 216863c48fd05b08e9b0083d61dcb163a2add62a Mon Sep 17 00:00:00 2001 From: Ben Straub Date: Wed, 17 Oct 2012 14:02:24 -0700 Subject: Fetch/indexer: progress callbacks --- include/git2/indexer.h | 13 ++++++++++++- include/git2/remote.h | 8 +++++++- src/clone.c | 2 +- src/fetch.c | 15 +++++++++++---- src/fetch.h | 16 ++++++++++++++-- src/indexer.c | 19 ++++++++++++++++++- src/remote.c | 8 ++++++-- tests-clar/network/fetch.c | 11 ++++++++++- 8 files changed, 79 insertions(+), 13 deletions(-) diff --git a/include/git2/indexer.h b/include/git2/indexer.h index 87f48fe27..0d3c9dd51 100644 --- a/include/git2/indexer.h +++ b/include/git2/indexer.h @@ -23,6 +23,11 @@ typedef struct git_indexer_stats { } git_indexer_stats; +/** + * Type for progress callbacks during indexing + */ +typedef void (*git_indexer_progress_callback)(const git_indexer_stats *stats, void *payload); + typedef struct git_indexer git_indexer; typedef struct git_indexer_stream git_indexer_stream; @@ -31,8 +36,14 @@ typedef struct git_indexer_stream git_indexer_stream; * * @param out where to store the indexer instance * @param path to the directory where the packfile should be stored + * @param progress_cb function to call with progress information + * @param progress_payload payload for the progress callback */ -GIT_EXTERN(int) git_indexer_stream_new(git_indexer_stream **out, const char *path); +GIT_EXTERN(int) git_indexer_stream_new( + git_indexer_stream **out, + const char *path, + git_indexer_progress_callback progress_cb, + void *progress_callback_payload); /** * Add data to the indexer diff --git a/include/git2/remote.h b/include/git2/remote.h index 9327320b4..ca75126f9 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -184,9 +184,15 @@ GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void * * @param remote the remote to download from * @param filename where to store the temporary filename + * @param progress_cb function to call with progress information + * @param progress_payload payload for the progress callback * @return 0 or an error code */ -GIT_EXTERN(int) git_remote_download(git_remote *remote, git_off_t *bytes); +GIT_EXTERN(int) git_remote_download( + git_remote *remote, + git_off_t *bytes, + git_indexer_progress_callback progress_cb, + void *progress_payload); /** * Check whether the remote is connected diff --git a/src/clone.c b/src/clone.c index 2000de6f3..0acf588b4 100644 --- a/src/clone.c +++ b/src/clone.c @@ -258,7 +258,7 @@ static int setup_remotes_and_fetch(git_repository *repo, const char *origin_url) if (!git_remote_add(&origin, repo, GIT_REMOTE_ORIGIN, origin_url)) { /* Connect and download everything */ if (!git_remote_connect(origin, GIT_DIR_FETCH)) { - if (!git_remote_download(origin, &bytes)) { + if (!git_remote_download(origin, &bytes, NULL, NULL)) { /* Create "origin/foo" branches for all remote branches */ if (!git_remote_update_tips(origin)) { /* Point HEAD to the same ref as the remote's head */ diff --git a/src/fetch.c b/src/fetch.c index 242946356..583c79a34 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -302,7 +302,11 @@ on_error: return error; } -int git_fetch_download_pack(git_remote *remote, git_off_t *bytes) +int git_fetch_download_pack( + git_remote *remote, + git_off_t *bytes, + git_indexer_progress_callback progress_cb, + void *progress_payload) { git_transport *t = remote->transport; @@ -312,7 +316,8 @@ int git_fetch_download_pack(git_remote *remote, git_off_t *bytes) if (t->own_logic) return t->download_pack(t, remote->repo, bytes, &remote->stats); - return git_fetch__download_pack(t, remote->repo, bytes, &remote->stats); + return git_fetch__download_pack(t, remote->repo, bytes, &remote->stats, + progress_cb, progress_payload); } @@ -348,7 +353,9 @@ int git_fetch__download_pack( git_transport *t, git_repository *repo, git_off_t *bytes, - git_indexer_stats *stats) + git_indexer_stats *stats, + git_indexer_progress_callback progress_cb, + void *progress_payload) { git_buf path = GIT_BUF_INIT; gitno_buffer *buf = &t->buffer; @@ -358,7 +365,7 @@ int git_fetch__download_pack( if (git_buf_joinpath(&path, git_repository_path(repo), "objects/pack") < 0) return -1; - if (git_indexer_stream_new(&idx, git_buf_cstr(&path)) < 0) + if (git_indexer_stream_new(&idx, git_buf_cstr(&path), progress_cb, progress_payload) < 0) goto on_error; git_buf_free(&path); diff --git a/src/fetch.h b/src/fetch.h index ae030c6eb..c10973422 100644 --- a/src/fetch.h +++ b/src/fetch.h @@ -10,9 +10,21 @@ #include "netops.h" int git_fetch_negotiate(git_remote *remote); -int git_fetch_download_pack(git_remote *remote, git_off_t *bytes); -int git_fetch__download_pack(git_transport *t, git_repository *repo, git_off_t *bytes, git_indexer_stats *stats); +int git_fetch_download_pack( + git_remote *remote, + git_off_t *bytes, + git_indexer_progress_callback progress_cb, + void *progress_payload); + +int git_fetch__download_pack( + git_transport *t, + git_repository *repo, + git_off_t *bytes, + git_indexer_stats *stats, + git_indexer_progress_callback progress_cb, + void *progress_payload); + int git_fetch_setup_walk(git_revwalk **out, git_repository *repo); #endif diff --git a/src/indexer.c b/src/indexer.c index 7d4e18d7a..2d032fbd3 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -49,6 +49,8 @@ struct git_indexer_stream { git_vector deltas; unsigned int fanout[256]; git_oid hash; + git_indexer_progress_callback progress_cb; + void *progress_payload; }; struct delta_info { @@ -138,7 +140,11 @@ static int cache_cmp(const void *a, const void *b) return git_oid_cmp(&ea->sha1, &eb->sha1); } -int git_indexer_stream_new(git_indexer_stream **out, const char *prefix) +int git_indexer_stream_new( + git_indexer_stream **out, + const char *prefix, + git_indexer_progress_callback progress_cb, + void *progress_payload) { git_indexer_stream *idx; git_buf path = GIT_BUF_INIT; @@ -147,6 +153,8 @@ int git_indexer_stream_new(git_indexer_stream **out, const char *prefix) idx = git__calloc(1, sizeof(git_indexer_stream)); GITERR_CHECK_ALLOC(idx); + idx->progress_cb = progress_cb; + idx->progress_payload = progress_payload; error = git_buf_joinpath(&path, prefix, suff); if (error < 0) @@ -273,6 +281,12 @@ on_error: return -1; } +static void do_progress_callback(git_indexer_stream *idx, git_indexer_stats *stats) +{ + if (!idx->progress_cb) return; + idx->progress_cb(stats, idx->progress_payload); +} + int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t size, git_indexer_stats *stats) { int error; @@ -326,6 +340,7 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz memset(stats, 0, sizeof(git_indexer_stats)); stats->total = (unsigned int)idx->nr_objects; + do_progress_callback(idx, stats); } /* Now that we have data in the pack, let's try to parse it */ @@ -362,6 +377,7 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz return error; stats->received++; + do_progress_callback(idx, stats); continue; } @@ -381,6 +397,7 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz stats->processed = (unsigned int)++processed; stats->received++; + do_progress_callback(idx, stats); } return 0; diff --git a/src/remote.c b/src/remote.c index 4b4044196..662b8cc9b 100644 --- a/src/remote.c +++ b/src/remote.c @@ -433,7 +433,11 @@ int git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void *payload) return 0; } -int git_remote_download(git_remote *remote, git_off_t *bytes) +int git_remote_download( + git_remote *remote, + git_off_t *bytes, + git_indexer_progress_callback progress_cb, + void *progress_payload) { int error; @@ -442,7 +446,7 @@ int git_remote_download(git_remote *remote, git_off_t *bytes) if ((error = git_fetch_negotiate(remote)) < 0) return error; - return git_fetch_download_pack(remote, bytes); + return git_fetch_download_pack(remote, bytes, progress_cb, progress_payload); } int git_remote_update_tips(git_remote *remote) diff --git a/tests-clar/network/fetch.c b/tests-clar/network/fetch.c index 1e9a2323e..134e8fe2e 100644 --- a/tests-clar/network/fetch.c +++ b/tests-clar/network/fetch.c @@ -28,11 +28,19 @@ static int update_tips(const char *refname, const git_oid *a, const git_oid *b, return 0; } +static void progress(const git_indexer_stats *stats, void *payload) +{ + GIT_UNUSED(stats); + bool *was_called = (bool*)payload; + *was_called = true; +} + static void do_fetch(const char *url, int flag, int n) { git_remote *remote; git_off_t bytes; git_remote_callbacks callbacks; + bool progress_was_called = false; memset(&callbacks, 0, sizeof(git_remote_callbacks)); callbacks.update_tips = update_tips; @@ -42,10 +50,11 @@ static void do_fetch(const char *url, int flag, int n) git_remote_set_callbacks(remote, &callbacks); git_remote_set_autotag(remote, flag); cl_git_pass(git_remote_connect(remote, GIT_DIR_FETCH)); - cl_git_pass(git_remote_download(remote, &bytes)); + cl_git_pass(git_remote_download(remote, &bytes, progress, &progress_was_called)); git_remote_disconnect(remote); cl_git_pass(git_remote_update_tips(remote)); cl_assert_equal_i(counter, n); + cl_assert_equal_i(progress_was_called, true); git_remote_free(remote); } -- cgit v1.2.1