summaryrefslogtreecommitdiff
path: root/examples/network/clone.c
blob: fd30bca5bcd783d6df39aec6fab43f2397628c99 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "common.h"
#include <git2.h>
#include <git2/clone.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>

typedef struct progress_data {
	git_indexer_stats fetch_progress;
	float checkout_progress;
	const char *path;
} progress_data;

static void print_progress(const progress_data *pd)
{
	int network_percent = (100*pd->fetch_progress.received) / pd->fetch_progress.total;
	int index_percent = (100*pd->fetch_progress.processed) / pd->fetch_progress.total;
	int checkout_percent = (int)(100.f * pd->checkout_progress);
	printf("net %3d%%  /  idx %3d%%  /  chk %3d%%  %50s\r",
			network_percent, index_percent, checkout_percent, pd->path);
	/*
	printf("net %5d /%5d  –  idx %5d /%5d  –  chk %.04f   %20s\r",
			pd->fetch_progress.received, pd->fetch_progress.total,
			pd->fetch_progress.processed, pd->fetch_progress.total,
			pd->checkout_progress, pd->path);
			*/
}

static void fetch_progress(const git_indexer_stats *stats, void *payload)
{
	progress_data *pd = (progress_data*)payload;
	pd->fetch_progress = *stats;
	print_progress(pd);
}
static void checkout_progress(const char *path, float progress, void *payload)
{
	progress_data *pd = (progress_data*)payload;
	pd->checkout_progress = progress;
	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_checkout_opts checkout_opts = {0};
	const char *url = argv[1];
	const char *path = argv[2];
	int error;

	// Validate args
	if (argc < 3) {
		printf ("USAGE: %s <url> <path>\n", argv[0]);
		return -1;
	}

	// Set up options
	checkout_opts.checkout_strategy = GIT_CHECKOUT_CREATE_MISSING;
	checkout_opts.progress_cb = checkout_progress;
	checkout_opts.progress_payload = &pd;

	// Do the clone
	error = git_clone(&cloned_repo, url, path, &fetch_progress, &pd, &checkout_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;
}