examples: modernise the fetch example Under normal conditions, git_remote_fetch() should be the only function used to perform a fetch. Don't let the example lead people astray.
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
diff --git a/examples/network/fetch.c b/examples/network/fetch.c
index 67444cb..b536959 100644
--- a/examples/network/fetch.c
+++ b/examples/network/fetch.c
@@ -23,32 +23,6 @@ static int progress_cb(const char *str, int len, void *data)
return 0;
}
-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_DIRECTION_FETCH, &data->fetch_opts->callbacks) < 0) {
- data->ret = -1;
- goto exit;
- }
-
- // 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, NULL, data->fetch_opts) < 0) {
- data->ret = -1;
- goto exit;
- }
-
- data->ret = 0;
-
-exit:
- data->finished = 1;
- return &data->ret;
-}
-
/**
* This function gets called for each remote-tracking branch that gets
* updated. The message we output depends on whether it's a new one or
@@ -73,6 +47,24 @@ static int update_cb(const char *refname, const git_oid *a, const git_oid *b, vo
return 0;
}
+/**
+ * This gets called during the download and indexing. 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.
+ */
+static int transfer_progress_cb(const git_transfer_progress *stats, void *payload)
+{
+ if (stats->received_objects == stats->total_objects) {
+ printf("Resolving deltas %d/%d\r",
+ stats->indexed_deltas, stats->total_deltas);
+ } else 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);
+ }
+}
+
/** Entry point for this command */
int fetch(git_repository *repo, int argc, char **argv)
{
@@ -80,9 +72,6 @@ int fetch(git_repository *repo, int argc, char **argv)
const git_transfer_progress *stats;
struct dl_data data;
git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
-#ifndef _WIN32
- pthread_t worker;
-#endif
if (argc < 2) {
fprintf(stderr, "usage: %s fetch <repo>\n", argv[-1]);
@@ -99,49 +88,23 @@ int fetch(git_repository *repo, int argc, char **argv)
// Set up the callbacks (only update_tips for now)
fetch_opts.callbacks.update_tips = &update_cb;
fetch_opts.callbacks.sideband_progress = &progress_cb;
+ fetch_opts.callbacks.transfer_progress = transfer_progress_cb;
fetch_opts.callbacks.credentials = cred_acquire_cb;
- // Set up the information for the background worker thread
- data.remote = remote;
- data.fetch_opts = &fetch_opts;
- 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->received_objects == stats->total_objects) {
- printf("Resolving deltas %d/%d\r",
- stats->indexed_deltas, stats->total_deltas);
- } else 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
+ /**
+ * Perform the fetch with the configured refspecs from the
+ * config. Update the reflog for the updated references with
+ * "fetch".
+ */
+ if (git_remote_fetch(remote, NULL, &fetch_opts, "fetch") < 0)
+ return -1;
/**
* If there are local objects (we got a thin pack), then tell
* the user how many objects we saved from having to cross the
* network.
*/
+ stats = git_remote_stats(remote);
if (stats->local_objects > 0) {
printf("\rReceived %d/%d objects in %zu bytes (used %d local objects)\n",
stats->indexed_objects, stats->total_objects, stats->received_bytes, stats->local_objects);
@@ -150,16 +113,6 @@ int fetch(git_repository *repo, int argc, char **argv)
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 needed objects are available locally.
- if (git_remote_update_tips(remote, &fetch_opts.callbacks, 1, fetch_opts.download_tags, NULL) < 0)
- return -1;
-
git_remote_free(remote);
return 0;