clone.c 3.11 KB
Newer Older
1
#include "common.h"
2

3
typedef struct progress_data {
4
	git_indexer_progress fetch_progress;
5 6
	size_t completed_steps;
	size_t total_steps;
7
	const char *path;
8
} progress_data;
9

10
static void print_progress(const progress_data *pd)
11
{
12 13 14 15 16 17 18
	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;

19
	int checkout_percent = pd->total_steps > 0
20
		? (int)((100 * pd->completed_steps) / pd->total_steps)
21
		: 0;
22
	size_t kbytes = pd->fetch_progress.received_bytes / 1024;
23

24 25
	if (pd->fetch_progress.total_objects &&
		pd->fetch_progress.received_objects == pd->fetch_progress.total_objects) {
26
		printf("Resolving deltas %u/%u\r",
27 28 29
		       pd->fetch_progress.indexed_deltas,
		       pd->fetch_progress.total_deltas);
	} else {
30
		printf("net %3d%% (%4" PRIuZ " kb, %5u/%5u)  /  idx %3d%% (%5u/%5u)  /  chk %3d%% (%4" PRIuZ "/%4" PRIuZ")%s\n",
31 32 33 34 35 36
		   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);
37
	}
38
}
39

40 41
static int sideband_progress(const char *str, int len, void *payload)
{
42
	(void)payload; /* unused */
43

44
	printf("remote: %.*s", len, str);
45 46 47 48
	fflush(stdout);
	return 0;
}

49
static int fetch_progress(const git_indexer_progress *stats, void *payload)
50 51 52 53
{
	progress_data *pd = (progress_data*)payload;
	pd->fetch_progress = *stats;
	print_progress(pd);
54
	return 0;
55
}
56
static void checkout_progress(const char *path, size_t cur, size_t tot, void *payload)
57 58
{
	progress_data *pd = (progress_data*)payload;
59 60
	pd->completed_steps = cur;
	pd->total_steps = tot;
61 62
	pd->path = path;
	print_progress(pd);
63 64
}

65

66
int lg2_clone(git_repository *repo, int argc, char **argv)
67
{
Ben Straub committed
68
	progress_data pd = {{0}};
69
	git_repository *cloned_repo = NULL;
70
	git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
71
	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
72 73 74
	const char *url = argv[1];
	const char *path = argv[2];
	int error;
75

76
	(void)repo; /* unused */
77

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

84
	/* Set up options */
85
	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
86 87
	checkout_opts.progress_cb = checkout_progress;
	checkout_opts.progress_payload = &pd;
88
	clone_opts.checkout_opts = checkout_opts;
89
	clone_opts.fetch_opts.callbacks.sideband_progress = sideband_progress;
90 91 92
	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;
Ben Straub committed
93

94
	/* Do the clone */
Ben Straub committed
95
	error = git_clone(&cloned_repo, url, path, &clone_opts);
96 97
	printf("\n");
	if (error != 0) {
98
		const git_error *err = git_error_last();
99 100 101 102 103
		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;
104
}