4 #include "run-command.h"
13 struct child_process *helper;
16 /* These go from remote name (as in "list") to private name */
17 struct refspec *refspecs;
21 static struct child_process *get_helper(struct transport *transport)
23 struct helper_data *data = transport->data;
24 struct strbuf buf = STRBUF_INIT;
25 struct child_process *helper;
27 const char **refspecs = NULL;
29 int refspec_alloc = 0;
34 helper = xcalloc(1, sizeof(*helper));
38 helper->argv = xcalloc(4, sizeof(*helper->argv));
39 strbuf_addf(&buf, "remote-%s", data->name);
40 helper->argv[0] = strbuf_detach(&buf, NULL);
41 helper->argv[1] = transport->remote->name;
42 helper->argv[2] = transport->url;
44 if (start_command(helper))
45 die("Unable to run helper: git %s", helper->argv[0]);
46 data->helper = helper;
48 write_str_in_full(helper->in, "capabilities\n");
50 file = xfdopen(helper->out, "r");
52 if (strbuf_getline(&buf, file, '\n') == EOF)
53 exit(128); /* child died, message supplied already */
57 if (!strcmp(buf.buf, "fetch"))
59 if (!strcmp(buf.buf, "import"))
61 if (!data->refspecs && !prefixcmp(buf.buf, "refspec ")) {
65 refspecs[refspec_nr++] = strdup(buf.buf + strlen("refspec "));
70 data->refspec_nr = refspec_nr;
71 data->refspecs = parse_fetch_refspec(refspec_nr, refspecs);
72 for (i = 0; i < refspec_nr; i++) {
73 free((char *)refspecs[i]);
81 static int disconnect_helper(struct transport *transport)
83 struct helper_data *data = transport->data;
85 write_str_in_full(data->helper->in, "\n");
86 close(data->helper->in);
87 finish_command(data->helper);
88 free((char *)data->helper->argv[0]);
89 free(data->helper->argv);
96 static int release_helper(struct transport *transport)
98 struct helper_data *data = transport->data;
99 free_refspec(data->refspec_nr, data->refspecs);
100 data->refspecs = NULL;
101 disconnect_helper(transport);
102 free(transport->data);
106 static int fetch_with_fetch(struct transport *transport,
107 int nr_heads, struct ref **to_fetch)
109 struct child_process *helper = get_helper(transport);
110 FILE *file = xfdopen(helper->out, "r");
112 struct strbuf buf = STRBUF_INIT;
114 for (i = 0; i < nr_heads; i++) {
115 const struct ref *posn = to_fetch[i];
116 if (posn->status & REF_STATUS_UPTODATE)
119 strbuf_addf(&buf, "fetch %s %s\n",
120 sha1_to_hex(posn->old_sha1), posn->name);
121 write_in_full(helper->in, buf.buf, buf.len);
124 if (strbuf_getline(&buf, file, '\n') == EOF)
125 exit(128); /* child died, message supplied already */
130 static int get_importer(struct transport *transport, struct child_process *fastimport)
132 struct child_process *helper = get_helper(transport);
133 memset(fastimport, 0, sizeof(*fastimport));
134 fastimport->in = helper->out;
135 fastimport->argv = xcalloc(5, sizeof(*fastimport->argv));
136 fastimport->argv[0] = "fast-import";
137 fastimport->argv[1] = "--quiet";
139 fastimport->git_cmd = 1;
140 return start_command(fastimport);
143 static int fetch_with_import(struct transport *transport,
144 int nr_heads, struct ref **to_fetch)
146 struct child_process fastimport;
147 struct child_process *helper = get_helper(transport);
148 struct helper_data *data = transport->data;
151 struct strbuf buf = STRBUF_INIT;
153 if (get_importer(transport, &fastimport))
154 die("Couldn't run fast-import");
156 for (i = 0; i < nr_heads; i++) {
158 if (posn->status & REF_STATUS_UPTODATE)
161 strbuf_addf(&buf, "import %s\n", posn->name);
162 write_in_full(helper->in, buf.buf, buf.len);
165 disconnect_helper(transport);
166 finish_command(&fastimport);
167 free(fastimport.argv);
168 fastimport.argv = NULL;
170 for (i = 0; i < nr_heads; i++) {
173 if (posn->status & REF_STATUS_UPTODATE)
176 private = apply_refspecs(data->refspecs, data->refspec_nr, posn->name);
178 private = strdup(posn->name);
179 read_ref(private, posn->old_sha1);
182 strbuf_release(&buf);
186 static int fetch(struct transport *transport,
187 int nr_heads, struct ref **to_fetch)
189 struct helper_data *data = transport->data;
193 for (i = 0; i < nr_heads; i++)
194 if (!(to_fetch[i]->status & REF_STATUS_UPTODATE))
201 return fetch_with_fetch(transport, nr_heads, to_fetch);
204 return fetch_with_import(transport, nr_heads, to_fetch);
209 static struct ref *get_refs_list(struct transport *transport, int for_push)
211 struct child_process *helper;
212 struct ref *ret = NULL;
213 struct ref **tail = &ret;
215 struct strbuf buf = STRBUF_INIT;
218 helper = get_helper(transport);
220 write_str_in_full(helper->in, "list\n");
222 file = xfdopen(helper->out, "r");
225 if (strbuf_getline(&buf, file, '\n') == EOF)
226 exit(128); /* child died, message supplied already */
231 eov = strchr(buf.buf, ' ');
233 die("Malformed response in ref list: %s", buf.buf);
234 eon = strchr(eov + 1, ' ');
238 *tail = alloc_ref(eov + 1);
239 if (buf.buf[0] == '@')
240 (*tail)->symref = xstrdup(buf.buf + 1);
241 else if (buf.buf[0] != '?')
242 get_sha1_hex(buf.buf, (*tail)->old_sha1);
243 tail = &((*tail)->next);
245 strbuf_release(&buf);
247 for (posn = ret; posn; posn = posn->next)
248 resolve_remote_symref(posn, ret);
253 int transport_helper_init(struct transport *transport, const char *name)
255 struct helper_data *data = xcalloc(sizeof(*data), 1);
258 transport->data = data;
259 transport->get_refs_list = get_refs_list;
260 transport->fetch = fetch;
261 transport->disconnect = release_helper;