]> git.proxmox.com Git - libgit2.git/blob - examples/network/clone.c
bbcd2e8487950d977e6fa23735550fc6d8be8ce6
[libgit2.git] / examples / network / clone.c
1 #include "common.h"
2 #include <git2.h>
3 #include <git2/clone.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #ifndef _WIN32
8 # include <pthread.h>
9 # include <unistd.h>
10 #endif
11
12 typedef struct progress_data {
13 git_transfer_progress fetch_progress;
14 size_t completed_steps;
15 size_t total_steps;
16 const char *path;
17 } progress_data;
18
19 static void print_progress(const progress_data *pd)
20 {
21 int network_percent = pd->fetch_progress.total_objects > 0 ?
22 (100*pd->fetch_progress.received_objects) / pd->fetch_progress.total_objects :
23 0;
24 int index_percent = pd->fetch_progress.total_objects > 0 ?
25 (100*pd->fetch_progress.indexed_objects) / pd->fetch_progress.total_objects :
26 0;
27
28 int checkout_percent = pd->total_steps > 0
29 ? (100 * pd->completed_steps) / pd->total_steps
30 : 0;
31 int kbytes = pd->fetch_progress.received_bytes / 1024;
32
33 if (pd->fetch_progress.total_objects &&
34 pd->fetch_progress.received_objects == pd->fetch_progress.total_objects) {
35 printf("Resolving deltas %d/%d\r",
36 pd->fetch_progress.indexed_deltas,
37 pd->fetch_progress.total_deltas);
38 } else {
39 printf("net %3d%% (%4d kb, %5d/%5d) / idx %3d%% (%5d/%5d) / chk %3d%% (%4" PRIuZ "/%4" PRIuZ ") %s\n",
40 network_percent, kbytes,
41 pd->fetch_progress.received_objects, pd->fetch_progress.total_objects,
42 index_percent, pd->fetch_progress.indexed_objects, pd->fetch_progress.total_objects,
43 checkout_percent,
44 pd->completed_steps, pd->total_steps,
45 pd->path);
46 }
47 }
48
49 static int sideband_progress(const char *str, int len, void *payload)
50 {
51 (void)payload; /* unused */
52
53 printf("remote: %.*s", len, str);
54 fflush(stdout);
55 return 0;
56 }
57
58 static int fetch_progress(const git_transfer_progress *stats, void *payload)
59 {
60 progress_data *pd = (progress_data*)payload;
61 pd->fetch_progress = *stats;
62 print_progress(pd);
63 return 0;
64 }
65 static void checkout_progress(const char *path, size_t cur, size_t tot, void *payload)
66 {
67 progress_data *pd = (progress_data*)payload;
68 pd->completed_steps = cur;
69 pd->total_steps = tot;
70 pd->path = path;
71 print_progress(pd);
72 }
73
74
75 int do_clone(git_repository *repo, int argc, char **argv)
76 {
77 progress_data pd = {{0}};
78 git_repository *cloned_repo = NULL;
79 git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
80 git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
81 const char *url = argv[1];
82 const char *path = argv[2];
83 int error;
84
85 (void)repo; /* unused */
86
87 /* Validate args */
88 if (argc < 3) {
89 printf ("USAGE: %s <url> <path>\n", argv[0]);
90 return -1;
91 }
92
93 /* Set up options */
94 checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
95 checkout_opts.progress_cb = checkout_progress;
96 checkout_opts.progress_payload = &pd;
97 clone_opts.checkout_opts = checkout_opts;
98 clone_opts.fetch_opts.callbacks.sideband_progress = sideband_progress;
99 clone_opts.fetch_opts.callbacks.transfer_progress = &fetch_progress;
100 clone_opts.fetch_opts.callbacks.credentials = cred_acquire_cb;
101 clone_opts.fetch_opts.callbacks.payload = &pd;
102
103 /* Do the clone */
104 error = git_clone(&cloned_repo, url, path, &clone_opts);
105 printf("\n");
106 if (error != 0) {
107 const git_error *err = git_error_last();
108 if (err) printf("ERROR %d: %s\n", err->klass, err->message);
109 else printf("ERROR %d: no detailed info\n", error);
110 }
111 else if (cloned_repo) git_repository_free(cloned_repo);
112 return error;
113 }