From d912491b55675c25bf07f765cfb621d0f3fd5ec4 Mon Sep 17 00:00:00 2001 From: ENGO150 Date: Sat, 11 Jun 2022 16:51:17 +0200 Subject: [PATCH] stealed some code and put it into 'git' files --- include/git.h | 2 + src/lib/git.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) diff --git a/include/git.h b/include/git.h index 3203bca..5e53118 100644 --- a/include/git.h +++ b/include/git.h @@ -1,6 +1,8 @@ #ifndef WHY2_GIT_H #define WHY2_GIT_H +#include +int cloneRepository(git_repository *repo, int argc, char **argv); // CLONES GIT REPOSITORY #endif \ No newline at end of file diff --git a/src/lib/git.c b/src/lib/git.c index e69de29..01ffe94 100644 --- a/src/lib/git.c +++ b/src/lib/git.c @@ -0,0 +1,145 @@ +/* + + NOTE: This is (almost) completely copied from: https://github.com/libgit2/libgit2/blob/main/examples/clone.c + + I HAVE NO IDEA HOW THIS SHIT WORKS!!! + +*/ + +#include + +#include +#include + +#ifndef PRIuZ +#if defined(_MSC_VER) || defined(__MINGW32__) +# define PRIuZ "Iu" +#else +# define PRIuZ "zu" +#endif +#endif + +extern int cred_acquire_cb +( + git_credential **out, + const char *url, + const char *username_from_url, + unsigned int allowed_types, + void *payload +); + +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; + + 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 cloneRepository(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; + + if (argc < 3) + { + printf ("USAGE: %s \n", argv[0]); + return -1; + } + + 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; + + 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; +} \ No newline at end of file