Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'examples/network/fetch.c')
-rw-r--r--examples/network/fetch.c150
1 files changed, 92 insertions, 58 deletions
diff --git a/examples/network/fetch.c b/examples/network/fetch.c
index f4a044984..6020ec6ec 100644
--- a/examples/network/fetch.c
+++ b/examples/network/fetch.c
@@ -3,23 +3,31 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <pthread.h>
+#ifndef _WIN32
+# include <pthread.h>
+# include <unistd.h>
+#endif
struct dl_data {
git_remote *remote;
- git_off_t *bytes;
- git_indexer_stats *stats;
int ret;
int finished;
};
+static void progress_cb(const char *str, int len, void *data)
+{
+ (void)data;
+ printf("remote: %.*s", len, str);
+ fflush(stdout); /* We don't have the \n to force the flush */
+}
+
static void *download(void *ptr)
{
struct dl_data *data = (struct dl_data *)ptr;
// Connect to the remote end specifying that we want to fetch
// information from it.
- if (git_remote_connect(data->remote, GIT_DIR_FETCH) < 0) {
+ if (git_remote_connect(data->remote, GIT_DIRECTION_FETCH) < 0) {
data->ret = -1;
goto exit;
}
@@ -27,7 +35,7 @@ static void *download(void *ptr)
// Download the packfile and index it. This function updates the
// amount of received data and the indexer stats which lets you
// inform the user about progress.
- if (git_remote_download(data->remote, data->bytes, data->stats) < 0) {
+ if (git_remote_download(data->remote, NULL, NULL) < 0) {
data->ret = -1;
goto exit;
}
@@ -36,13 +44,13 @@ static void *download(void *ptr)
exit:
data->finished = 1;
- pthread_exit(&data->ret);
+ return &data->ret;
}
-int update_cb(const char *refname, const git_oid *a, const git_oid *b)
+static 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];
+ (void)data;
git_oid_fmt(b_str, b);
b_str[GIT_OID_HEXSZ] = '\0';
@@ -60,54 +68,80 @@ int update_cb(const char *refname, const git_oid *a, const git_oid *b)
int fetch(git_repository *repo, int argc, char **argv)
{
- git_remote *remote = NULL;
- git_off_t bytes = 0;
- git_indexer_stats stats;
- pthread_t worker;
- struct dl_data data;
-
- // Figure out whether it's a named remote or a URL
- printf("Fetching %s\n", argv[1]);
- if (git_remote_load(&remote, repo, argv[1]) < 0) {
- if (git_remote_new(&remote, repo, NULL, argv[1], NULL) < 0)
- return -1;
- }
-
- // Set up the information for the background worker thread
- data.remote = remote;
- data.bytes = &bytes;
- data.stats = &stats;
- data.ret = 0;
- data.finished = 0;
- memset(&stats, 0, sizeof(stats));
-
- pthread_create(&worker, NULL, download, &data);
-
- // Loop while the worker thread is still running. Here we show processed
- // and total objects in the pack and the amount of received
- // data. Most frontends will probably want to show a percentage and
- // the download rate.
- do {
- usleep(10000);
- printf("\rReceived %d/%d objects in %d bytes", stats.processed, stats.total, bytes);
- } while (!data.finished);
- printf("\rReceived %d/%d objects in %d bytes\n", stats.processed, stats.total, bytes);
-
- // Disconnect the underlying connection to prevent from idling.
- git_remote_disconnect(remote);
-
- // Update the references in the remote's namespace to point to the
- // 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)
- return -1;
-
- git_remote_free(remote);
-
- return 0;
-
-on_error:
- git_remote_free(remote);
- return -1;
+ git_remote *remote = NULL;
+ const git_transfer_progress *stats;
+ struct dl_data data;
+ git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
+#ifndef _WIN32
+ pthread_t worker;
+#endif
+
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s fetch <repo>\n", argv[-1]);
+ return EXIT_FAILURE;
+ }
+
+ // Figure out whether it's a named remote or a URL
+ printf("Fetching %s for repo %p\n", argv[1], repo);
+ if (git_remote_load(&remote, repo, argv[1]) < 0) {
+ if (git_remote_create_inmemory(&remote, repo, NULL, argv[1]) < 0)
+ return -1;
+ }
+
+ // Set up the callbacks (only update_tips for now)
+ callbacks.update_tips = &update_cb;
+ callbacks.progress = &progress_cb;
+ git_remote_set_callbacks(remote, &callbacks);
+
+ // Set up the information for the background worker thread
+ data.remote = remote;
+ data.ret = 0;
+ data.finished = 0;
+
+ stats = git_remote_stats(remote);
+
+#ifdef _WIN32
+ download(&data);
+#else
+ pthread_create(&worker, NULL, download, &data);
+
+ // Loop while the worker thread is still running. Here we show processed
+ // and total objects in the pack and the amount of received
+ // data. Most frontends will probably want to show a percentage and
+ // the download rate.
+ do {
+ usleep(10000);
+
+ if (stats->total_objects > 0)
+ printf("Received %d/%d objects (%d) in %" PRIuZ " bytes\r",
+ stats->received_objects, stats->total_objects,
+ stats->indexed_objects, stats->received_bytes);
+ } while (!data.finished);
+
+ if (data.ret < 0)
+ goto on_error;
+
+ pthread_join(worker, NULL);
+#endif
+
+ printf("\rReceived %d/%d objects in %zu bytes\n",
+ stats->indexed_objects, stats->total_objects, stats->received_bytes);
+
+ // Disconnect the underlying connection to prevent from idling.
+ git_remote_disconnect(remote);
+
+ // Update the references in the remote's namespace to point to the
+ // 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) < 0)
+ return -1;
+
+ git_remote_free(remote);
+
+ return 0;
+
+ on_error:
+ git_remote_free(remote);
+ return -1;
}