summaryrefslogtreecommitdiffstats
path: root/examples/fetch.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/fetch.c')
-rw-r--r--examples/fetch.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/examples/fetch.c b/examples/fetch.c
new file mode 100644
index 0000000..bbd882c
--- /dev/null
+++ b/examples/fetch.c
@@ -0,0 +1,109 @@
+#include "common.h"
+
+static int 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 */
+ return 0;
+}
+
+/**
+ * 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
+ * an update.
+ */
+static int update_cb(const char *refname, const git_oid *a, const git_oid *b, void *data)
+{
+ char a_str[GIT_OID_SHA1_HEXSIZE+1], b_str[GIT_OID_SHA1_HEXSIZE+1];
+ (void)data;
+
+ git_oid_fmt(b_str, b);
+ b_str[GIT_OID_SHA1_HEXSIZE] = '\0';
+
+ if (git_oid_is_zero(a)) {
+ printf("[new] %.20s %s\n", b_str, refname);
+ } else {
+ git_oid_fmt(a_str, a);
+ a_str[GIT_OID_SHA1_HEXSIZE] = '\0';
+ printf("[updated] %.10s..%.10s %s\n", a_str, b_str, refname);
+ }
+
+ 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_indexer_progress *stats, void *payload)
+{
+ (void)payload;
+
+ if (stats->received_objects == stats->total_objects) {
+ printf("Resolving deltas %u/%u\r",
+ stats->indexed_deltas, stats->total_deltas);
+ } else if (stats->total_objects > 0) {
+ printf("Received %u/%u objects (%u) in %" PRIuZ " bytes\r",
+ stats->received_objects, stats->total_objects,
+ stats->indexed_objects, stats->received_bytes);
+ }
+ return 0;
+}
+
+/** Entry point for this command */
+int lg2_fetch(git_repository *repo, int argc, char **argv)
+{
+ git_remote *remote = NULL;
+ const git_indexer_progress *stats;
+ git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
+
+ 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_lookup(&remote, repo, argv[1]) < 0)
+ if (git_remote_create_anonymous(&remote, repo, argv[1]) < 0)
+ goto on_error;
+
+ /* 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;
+
+ /**
+ * 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)
+ goto on_error;
+
+ /**
+ * 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 %u/%u objects in %" PRIuZ " bytes (used %u local objects)\n",
+ stats->indexed_objects, stats->total_objects, stats->received_bytes, stats->local_objects);
+ } else{
+ printf("\rReceived %u/%u objects in %" PRIuZ "bytes\n",
+ stats->indexed_objects, stats->total_objects, stats->received_bytes);
+ }
+
+ git_remote_free(remote);
+
+ return 0;
+
+ on_error:
+ git_remote_free(remote);
+ return -1;
+}