mirror of
				https://git.proxmox.com/git/libgit2
				synced 2025-10-31 19:49:16 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			98 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "common.h"
 | |
| #include <git2.h>
 | |
| #include <git2/clone.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #ifndef _WIN32
 | |
| # include <pthread.h>
 | |
| # include <unistd.h>
 | |
| #endif
 | |
| 
 | |
| typedef struct progress_data {
 | |
| 	git_transfer_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 = (100*pd->fetch_progress.received_objects) / pd->fetch_progress.total_objects;
 | |
| 	int index_percent = (100*pd->fetch_progress.indexed_objects) / pd->fetch_progress.total_objects;
 | |
| 	int checkout_percent = pd->total_steps > 0
 | |
| 		? (100 * pd->completed_steps) / pd->total_steps
 | |
| 		: 0;
 | |
| 	int kbytes = pd->fetch_progress.received_bytes / 1024;
 | |
| 
 | |
| 	if (pd->fetch_progress.received_objects == pd->fetch_progress.total_objects) {
 | |
| 		printf("Resolving deltas %d/%d\r",
 | |
| 		       pd->fetch_progress.indexed_deltas,
 | |
| 		       pd->fetch_progress.total_deltas);
 | |
| 	} else {
 | |
| 		printf("net %3d%% (%4d kb, %5d/%5d)  /  idx %3d%% (%5d/%5d)  /  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 fetch_progress(const git_transfer_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 do_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_CREATE;
 | |
| 	checkout_opts.progress_cb = checkout_progress;
 | |
| 	checkout_opts.progress_payload = &pd;
 | |
| 	clone_opts.checkout_opts = checkout_opts;
 | |
| 	clone_opts.remote_callbacks.transfer_progress = &fetch_progress;
 | |
| 	clone_opts.remote_callbacks.credentials = cred_acquire_cb;
 | |
| 	clone_opts.remote_callbacks.payload = &pd;
 | |
| 
 | |
| 	// Do the clone
 | |
| 	error = git_clone(&cloned_repo, url, path, &clone_opts);
 | |
| 	printf("\n");
 | |
| 	if (error != 0) {
 | |
| 		const git_error *err = giterr_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;
 | |
| }
 | 
