summaryrefslogtreecommitdiffstats
path: root/examples/clone.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/clone.c')
-rw-r--r--examples/clone.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/examples/clone.c b/examples/clone.c
new file mode 100644
index 0000000..22d9d9b
--- /dev/null
+++ b/examples/clone.c
@@ -0,0 +1,104 @@
+#include "common.h"
+
+typedef struct progress_data {
+ git_indexer_progress fetch_progress;
+ size_t completed_steps;
+ size_t total_steps;
+ const char *path;
+} progress_data;
+
+static void print_progress(const progress_data *pd)
+{
+ int network_percent = pd->fetch_progress.total_objects > 0 ?
+ (100*pd->fetch_progress.received_objects) / pd->fetch_progress.total_objects :
+ 0;
+ int index_percent = pd->fetch_progress.total_objects > 0 ?
+ (100*pd->fetch_progress.indexed_objects) / pd->fetch_progress.total_objects :
+ 0;
+
+ int checkout_percent = pd->total_steps > 0
+ ? (int)((100 * pd->completed_steps) / pd->total_steps)
+ : 0;
+ size_t kbytes = pd->fetch_progress.received_bytes / 1024;
+
+ if (pd->fetch_progress.total_objects &&
+ pd->fetch_progress.received_objects == pd->fetch_progress.total_objects) {
+ printf("Resolving deltas %u/%u\r",
+ pd->fetch_progress.indexed_deltas,
+ pd->fetch_progress.total_deltas);
+ } else {
+ printf("net %3d%% (%4" PRIuZ " kb, %5u/%5u) / idx %3d%% (%5u/%5u) / chk %3d%% (%4" PRIuZ "/%4" PRIuZ")%s\n",
+ network_percent, kbytes,
+ pd->fetch_progress.received_objects, pd->fetch_progress.total_objects,
+ index_percent, pd->fetch_progress.indexed_objects, pd->fetch_progress.total_objects,
+ checkout_percent,
+ pd->completed_steps, pd->total_steps,
+ pd->path);
+ }
+}
+
+static int sideband_progress(const char *str, int len, void *payload)
+{
+ (void)payload; /* unused */
+
+ printf("remote: %.*s", len, str);
+ fflush(stdout);
+ return 0;
+}
+
+static int fetch_progress(const git_indexer_progress *stats, void *payload)
+{
+ progress_data *pd = (progress_data*)payload;
+ pd->fetch_progress = *stats;
+ print_progress(pd);
+ return 0;
+}
+static void checkout_progress(const char *path, size_t cur, size_t tot, void *payload)
+{
+ progress_data *pd = (progress_data*)payload;
+ pd->completed_steps = cur;
+ pd->total_steps = tot;
+ pd->path = path;
+ print_progress(pd);
+}
+
+
+int lg2_clone(git_repository *repo, int argc, char **argv)
+{
+ progress_data pd = {{0}};
+ git_repository *cloned_repo = NULL;
+ git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
+ git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
+ const char *url = argv[1];
+ const char *path = argv[2];
+ int error;
+
+ (void)repo; /* unused */
+
+ /* Validate args */
+ if (argc < 3) {
+ printf ("USAGE: %s <url> <path>\n", argv[0]);
+ return -1;
+ }
+
+ /* Set up options */
+ checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+ checkout_opts.progress_cb = checkout_progress;
+ checkout_opts.progress_payload = &pd;
+ clone_opts.checkout_opts = checkout_opts;
+ clone_opts.fetch_opts.callbacks.sideband_progress = sideband_progress;
+ clone_opts.fetch_opts.callbacks.transfer_progress = &fetch_progress;
+ clone_opts.fetch_opts.callbacks.credentials = cred_acquire_cb;
+ clone_opts.fetch_opts.callbacks.payload = &pd;
+
+ /* Do the clone */
+ error = git_clone(&cloned_repo, url, path, &clone_opts);
+ printf("\n");
+ if (error != 0) {
+ const git_error *err = git_error_last();
+ if (err) printf("ERROR %d: %s\n", err->klass, err->message);
+ else printf("ERROR %d: no detailed info\n", error);
+ }
+ else if (cloned_repo) git_repository_free(cloned_repo);
+ return error;
+}