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