]> git.proxmox.com Git - libgit2.git/commitdiff
Fetch/indexer: progress callbacks
authorBen Straub <bs@github.com>
Wed, 17 Oct 2012 21:02:24 +0000 (14:02 -0700)
committerBen Straub <bs@github.com>
Sat, 20 Oct 2012 02:36:22 +0000 (19:36 -0700)
include/git2/indexer.h
include/git2/remote.h
src/clone.c
src/fetch.c
src/fetch.h
src/indexer.c
src/remote.c
tests-clar/network/fetch.c

index 87f48fe277c96cda1ed0c4e6e19c3925ca58cbc1..0d3c9dd518e3dcd3e2deeaaacfeec2e83edc047b 100644 (file)
@@ -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
index 9327320b4912dea4de01ca579c09194912bbc054..ca75126f91db579dcc0608e77f7ca14214537521 100644 (file)
@@ -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
index 2000de6f3ca385be597bd08b88285b473eb8bafe..0acf588b4dfcc56b074fccac7afc41df4acdb54b 100644 (file)
@@ -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 */
index 2429463560b49d77dbb43d3837719292382b915e..583c79a349aa950e0e33b1a0e5b22162ca256371 100644 (file)
@@ -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);
index ae030c6eb92fbee3e8d118fc90a3b44870a1cf6d..c109734221dfd0555a1f9735494a82468c7cd94a 100644 (file)
 #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
index 7d4e18d7a9a43b7998b9ddb3fba7f23af8b52a34..2d032fbd33d39829138f2677e15e1a42bdf6b9b5 100644 (file)
@@ -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;
index 4b4044196f1d7cc333c67d1c993693fa113ffd6e..662b8cc9bd564b7d1522e3571d348dfe67e842db 100644 (file)
@@ -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)
index 1e9a2323e39d4c7058b5cfbadcb19b239af78958..134e8fe2e767c5e3ab14159dfb22a28788a0323a 100644 (file)
@@ -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);
 }