3 #include <git2/clone.h>
10 /* Shamelessly borrowed from http://stackoverflow.com/questions/3417837/ */
12 #elif defined(__GNUC__)
13 # define UNUSED(x) UNUSED_ ## x __attribute__((unused))
14 #elif defined(__LCLINT__)
15 # define UNUSED(x) /*@unused@*/ x
20 typedef struct progress_data
{
21 git_transfer_progress fetch_progress
;
22 size_t completed_steps
;
27 static void print_progress(const progress_data
*pd
)
29 int network_percent
= (100*pd
->fetch_progress
.received_objects
) / pd
->fetch_progress
.total_objects
;
30 int index_percent
= (100*pd
->fetch_progress
.indexed_objects
) / pd
->fetch_progress
.total_objects
;
31 int checkout_percent
= pd
->total_steps
> 0
32 ? (100 * pd
->completed_steps
) / pd
->total_steps
34 int kbytes
= pd
->fetch_progress
.received_bytes
/ 1024;
36 printf("net %3d%% (%4d kb, %5d/%5d) / idx %3d%% (%5d/%5d) / chk %3d%% (%4" PRIuZ
"/%4" PRIuZ
") %s\n",
37 network_percent
, kbytes
,
38 pd
->fetch_progress
.received_objects
, pd
->fetch_progress
.total_objects
,
39 index_percent
, pd
->fetch_progress
.indexed_objects
, pd
->fetch_progress
.total_objects
,
41 pd
->completed_steps
, pd
->total_steps
,
45 static void fetch_progress(const git_transfer_progress
*stats
, void *payload
)
47 progress_data
*pd
= (progress_data
*)payload
;
48 pd
->fetch_progress
= *stats
;
51 static void checkout_progress(const char *path
, size_t cur
, size_t tot
, void *payload
)
53 progress_data
*pd
= (progress_data
*)payload
;
54 pd
->completed_steps
= cur
;
55 pd
->total_steps
= tot
;
60 static int cred_acquire(git_cred
**out
,
61 const char * UNUSED(url
),
62 unsigned int UNUSED(allowed_types
),
63 void * UNUSED(payload
))
65 char username
[128] = {0};
66 char password
[128] = {0};
69 scanf("%s", username
);
71 /* Yup. Right there on your terminal. Careful where you copy/paste output. */
73 scanf("%s", password
);
75 return git_cred_userpass_plaintext_new(out
, username
, password
);
78 int do_clone(git_repository
*repo
, int argc
, char **argv
)
80 progress_data pd
= {{0}};
81 git_repository
*cloned_repo
= NULL
;
82 git_clone_options clone_opts
= GIT_CLONE_OPTIONS_INIT
;
83 git_checkout_opts checkout_opts
= GIT_CHECKOUT_OPTS_INIT
;
84 const char *url
= argv
[1];
85 const char *path
= argv
[2];
92 printf ("USAGE: %s <url> <path>\n", argv
[0]);
97 clone_opts
.checkout_opts
= &checkout_opts
;
98 checkout_opts
.checkout_strategy
= GIT_CHECKOUT_SAFE
;
99 checkout_opts
.progress_cb
= checkout_progress
;
100 checkout_opts
.progress_payload
= &pd
;
101 clone_opts
.fetch_progress_cb
= &fetch_progress
;
102 clone_opts
.fetch_progress_payload
= &pd
;
103 clone_opts
.cred_acquire_cb
= cred_acquire
;
106 error
= git_clone(&cloned_repo
, url
, path
, &clone_opts
);
109 const git_error
*err
= giterr_last();
110 if (err
) printf("ERROR %d: %s\n", err
->klass
, err
->message
);
111 else printf("ERROR %d: no detailed info\n", error
);
113 else if (cloned_repo
) git_repository_free(cloned_repo
);