remote-curl: Refactor walker initialization
[git/dscho.git] / remote-curl.c
blob478f3ea7d3849d3dccc870ca4e9a6f779e8504c7
1 #include "cache.h"
2 #include "remote.h"
3 #include "strbuf.h"
4 #include "walker.h"
5 #include "http.h"
6 #include "exec_cmd.h"
8 static struct remote *remote;
9 static const char *url;
10 static struct walker *walker;
12 static void init_walker(void)
14 if (!walker)
15 walker = get_http_walker(url, remote);
18 static struct ref *get_refs(void)
20 struct strbuf buffer = STRBUF_INIT;
21 char *data, *start, *mid;
22 char *ref_name;
23 char *refs_url;
24 int i = 0;
25 int http_ret;
27 struct ref *refs = NULL;
28 struct ref *ref = NULL;
29 struct ref *last_ref = NULL;
31 refs_url = xmalloc(strlen(url) + 11);
32 sprintf(refs_url, "%s/info/refs", url);
34 init_walker();
35 http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
36 switch (http_ret) {
37 case HTTP_OK:
38 break;
39 case HTTP_MISSING_TARGET:
40 die("%s not found: did you run git update-server-info on the"
41 " server?", refs_url);
42 default:
43 http_error(refs_url, http_ret);
44 die("HTTP request failed");
47 data = buffer.buf;
48 start = NULL;
49 mid = data;
50 while (i < buffer.len) {
51 if (!start) {
52 start = &data[i];
54 if (data[i] == '\t')
55 mid = &data[i];
56 if (data[i] == '\n') {
57 data[i] = 0;
58 ref_name = mid + 1;
59 ref = xmalloc(sizeof(struct ref) +
60 strlen(ref_name) + 1);
61 memset(ref, 0, sizeof(struct ref));
62 strcpy(ref->name, ref_name);
63 get_sha1_hex(start, ref->old_sha1);
64 if (!refs)
65 refs = ref;
66 if (last_ref)
67 last_ref->next = ref;
68 last_ref = ref;
69 start = NULL;
71 i++;
74 strbuf_release(&buffer);
76 ref = alloc_ref("HEAD");
77 if (!walker->fetch_ref(walker, ref) &&
78 !resolve_remote_symref(ref, refs)) {
79 ref->next = refs;
80 refs = ref;
81 } else {
82 free(ref);
85 strbuf_release(&buffer);
86 free(refs_url);
87 return refs;
90 int main(int argc, const char **argv)
92 struct strbuf buf = STRBUF_INIT;
94 git_extract_argv0_path(argv[0]);
95 setup_git_directory();
96 if (argc < 2) {
97 fprintf(stderr, "Remote needed\n");
98 return 1;
101 remote = remote_get(argv[1]);
103 if (argc > 2) {
104 url = argv[2];
105 } else {
106 url = remote->url[0];
109 do {
110 if (strbuf_getline(&buf, stdin, '\n') == EOF)
111 break;
112 if (!prefixcmp(buf.buf, "fetch ")) {
113 char *obj = buf.buf + strlen("fetch ");
114 init_walker();
115 walker->get_all = 1;
116 walker->get_tree = 1;
117 walker->get_history = 1;
118 walker->get_verbosely = 0;
119 walker->get_recover = 0;
120 if (walker_fetch(walker, 1, &obj, NULL, NULL))
121 die("Fetch failed.");
122 printf("\n");
123 fflush(stdout);
124 } else if (!strcmp(buf.buf, "list")) {
125 struct ref *refs = get_refs();
126 struct ref *posn;
127 for (posn = refs; posn; posn = posn->next) {
128 if (posn->symref)
129 printf("@%s %s\n", posn->symref, posn->name);
130 else
131 printf("%s %s\n", sha1_to_hex(posn->old_sha1), posn->name);
133 printf("\n");
134 fflush(stdout);
135 } else if (!strcmp(buf.buf, "capabilities")) {
136 printf("fetch\n");
137 printf("\n");
138 fflush(stdout);
139 } else {
140 return 1;
142 strbuf_reset(&buf);
143 } while (1);
144 return 0;