WIP fetch command, very dirty
[gitlite/.git] / gitlite.c
CommitLineData
41465307 1#include <getopt.h>
a374efd8 2#include <libgen.h>
285daa47
SB
3#include <stdio.h>
4#include <stdlib.h>
a374efd8
SB
5#include <string.h>
6#include <sys/param.h>
e545bdd1 7#include <sys/types.h>
41465307 8#include <sysexits.h>
a374efd8 9#include <unistd.h>
285daa47 10
285daa47
SB
11#include <git2/clone.h>
12#include <git2/errors.h>
41465307 13#include <git2/global.h>
285daa47 14
e545bdd1
SB
15#define PRIuZ "zu"
16
17#include "callbacks.h"
18
19
285daa47
SB
20// Compile with:
21// clang90 -o gitlite gitlite.c -lgit2 -I/usr/local/include -L/usr/local/lib -g
22
41465307
SB
23extern char *__progname;
24
285daa47 25void
41465307
SB
26git_bail_error(int rc) {
27 const git_error *err = NULL;
285daa47
SB
28
29 if (rc < 0) {
30 err = git_error_last();
41465307
SB
31 if (err)
32 printf("ERROR %d: %s\n", err->klass, err->message);
33 else
34 printf("ERROR %d: cannot fetch error info\n", rc);
35 }
e545bdd1
SB
36
37// exit(rc);
285daa47
SB
38}
39
a374efd8 40void
41465307 41util_stripext(char *path) {
a374efd8
SB
42 char *end = path + strlen(path);
43
44 while (end > path && *end != '.') {
45 --end;
46 }
47
48 if (end > path) {
49 *end = '\0';
50 }
51}
52
41465307
SB
53static
54void usage(void) {
55 fprintf(stderr, "usage: %s --<git-cmd> ...\n", __progname);
56 fprintf(stderr, "usage: %s --clone <git-url> [local-path]\n", __progname);
57}
58
285daa47 59int
41465307 60main(int argc, char *argv[]) {
285daa47 61 int rc;
41465307
SB
62 int ch = 0;
63 int opt_index = -1;
64 int do_clone, do_fetch, do_log = 0;
a374efd8 65 char buff[MAXPATHLEN];
41465307 66 char *url = NULL;
a374efd8
SB
67 char *ext = NULL;
68 char *local_path = NULL;
285daa47
SB
69 git_repository *cloned_repo = NULL;
70
41465307
SB
71 static struct option longopts[] = {
72 {"clone", required_argument, NULL, 'c'},
73 {"fetch", no_argument, NULL, 'f'},
74 {"log", no_argument, NULL, 'l'},
75 {NULL, 0, NULL, 0}
76 };
285daa47 77
a374efd8 78 if (argc == 1) {
41465307
SB
79 usage();
80 return (EX_USAGE);
a374efd8
SB
81 }
82
41465307
SB
83 while ((ch = getopt_long(argc, argv, "c:fl", longopts, &opt_index)) != -1) {
84 switch (ch) {
85 case 'c':
86 do_clone = 1;
87 url = optarg;
88 break;
89 case 'f':
90 do_fetch = 1;
91 break;
92 case 'l':
93 do_log = 1;
94 break;
95 default:
96 usage();
97 return (EX_USAGE);
98 }
99 }
100 argc -= optind;
101 argv += optind;
102
103 if (do_clone) {
104 printf("handle git clone command\n");
105
106 git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
107 git_checkout_options co_opts = GIT_CHECKOUT_OPTIONS_INIT;
108
109 co_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
110 co_opts.progress_cb = NULL;
111 co_opts.progress_payload = NULL;
112 clone_opts.checkout_opts = co_opts;
113 clone_opts.fetch_opts.callbacks.sideband_progress = NULL;
114 clone_opts.fetch_opts.callbacks.transfer_progress = NULL;
115 clone_opts.fetch_opts.callbacks.credentials = NULL;
116 clone_opts.fetch_opts.callbacks.payload = NULL;
117
118 rc = git_libgit2_init();
119 git_bail_error(rc);
120
121 local_path = argv[0];
122 if (local_path == NULL) {
123 ext = strdup(basename(__DECONST(char *, url)));
124 util_stripext(__DECONST(char *, ext));
125 asprintf(&local_path, "%s/%s", getwd(buff), ext);
126 }
127
128 rc = git_clone(&cloned_repo, url, local_path, &clone_opts);
129 git_bail_error(rc);
130
131 } else if (do_fetch) {
132 fprintf(stderr, "handle git fetch command\n");
e545bdd1
SB
133
134 rc = git_libgit2_init();
135 git_bail_error(rc);
136
137 git_repository *repo = NULL;
138
139 rc = git_repository_open(&repo, argv[0]);
140 git_bail_error(rc);
141
142
143 git_remote *remote = NULL;
144 rc = git_remote_lookup(&remote, repo, "origin");
145 git_bail_error(rc);
146
147
148 const git_indexer_progress *stats;
149 git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
150 fetch_opts.callbacks.update_tips = &update_cb;
151 fetch_opts.callbacks.sideband_progress = &progress_cb;
152 fetch_opts.callbacks.transfer_progress = transfer_progress_cb;
153 fetch_opts.callbacks.credentials = NULL;
154
155 //rc = git_remote_add_fetch(repo, "origin", "master");
156 //git_bail_error(rc);
157 printf("Fetching %s for repo %p\n", argv[0], repo);
158 rc = git_remote_fetch(remote, NULL, &fetch_opts, "fetch");
159 git_bail_error(rc);
160
161 __asm("int $3");
162 stats = git_remote_stats(remote);
163
164 if (stats->local_objects > 0) {
165 printf("\rReceived %u/%u objects in %" PRIuZ " bytes (used %u local objects)\n", stats->indexed_objects, stats->total_objects, stats->received_bytes, stats->local_objects);
166 } else{
167 printf("\rReceived %u/%u objects in %" PRIuZ "bytes\n", stats->indexed_objects, stats->total_objects, stats->received_bytes);
168 }
169
170 git_remote_free(remote);
41465307
SB
171
172 } else if (do_log) {
173 fprintf(stderr, "handle git log command\n");
174 return (-1);
a374efd8 175 }
285daa47
SB
176
177 if (cloned_repo)
178 git_repository_free(cloned_repo);
179
180 rc = git_libgit2_shutdown();
181 git_bail_error(rc);
182
a374efd8
SB
183 if (ext != NULL)
184 free(ext);
185
41465307 186 return (rc);
285daa47 187}