10
#include "string-list.h"
11
#include "thread-utils.h"
12
#include "sigchain.h"
13
+#include "argv-array.h"
14
15
static int debug;
16
20
FILE *out;
21
unsigned fetch : 1,
22
import : 1,
23
+ bidi_import : 1,
24
export : 1,
25
option : 1,
26
push : 1,
103
static struct child_process *get_helper(struct transport *transport)
104
{
105
struct helper_data *data = transport->data;
106
+ struct argv_array argv = ARGV_ARRAY_INIT;
107
struct strbuf buf = STRBUF_INIT;
108
struct child_process *helper;
109
const char **refspecs = NULL;
125
helper->in = -1;
126
helper->out = -1;
127
helper->err = 0;
125
- helper->argv = xcalloc(4, sizeof(*helper->argv));
126
- strbuf_addf(&buf, "git-remote-%s", data->name);
127
- helper->argv[0] = strbuf_detach(&buf, NULL);
128
- helper->argv[1] = transport->remote->name;
129
- helper->argv[2] = remove_ext_force(transport->url);
128
+ argv_array_pushf(&argv, "git-remote-%s", data->name);
129
+ argv_array_push(&argv, transport->remote->name);
130
+ argv_array_push(&argv, remove_ext_force(transport->url));
131
+ helper->argv = argv_array_detach(&argv, NULL);
132
helper->git_cmd = 0;
133
helper->silent_exec_failure = 1;
134
180
data->push = 1;
181
else if (!strcmp(capname, "import"))
182
data->import = 1;
183
+ else if (!strcmp(capname, "bidi-import"))
184
+ data->bidi_import = 1;
185
else if (!strcmp(capname, "export"))
186
data->export = 1;
187
else if (!data->refspecs && !prefixcmp(capname, "refspec ")) {
245
close(data->helper->out);
246
fclose(data->out);
247
res = finish_command(data->helper);
244
- free((char *)data->helper->argv[0]);
245
- free(data->helper->argv);
248
+ argv_array_free_detached(data->helper->argv);
249
free(data->helper);
250
data->helper = NULL;
251
}
379
static int get_importer(struct transport *transport, struct child_process *fastimport)
380
{
381
struct child_process *helper = get_helper(transport);
382
+ struct helper_data *data = transport->data;
383
+ struct argv_array argv = ARGV_ARRAY_INIT;
384
+ int cat_blob_fd, code;
385
memset(fastimport, 0, sizeof(*fastimport));
386
fastimport->in = helper->out;
381
- fastimport->argv = xcalloc(5, sizeof(*fastimport->argv));
382
- fastimport->argv[0] = "fast-import";
383
- fastimport->argv[1] = "--quiet";
387
+ argv_array_push(&argv, "fast-import");
388
+ argv_array_push(&argv, "--quiet");
389
390
+ if (data->bidi_import) {
391
+ cat_blob_fd = xdup(helper->in);
392
+ argv_array_pushf(&argv, "--cat-blob-fd=%d", cat_blob_fd);
393
+ }
394
+ fastimport->argv = argv.argv;
395
fastimport->git_cmd = 1;
386
- return start_command(fastimport);
396
+
397
+ code = start_command(fastimport);
398
+ return code;
399
}
400
401
static int get_exporter(struct transport *transport,
450
}
451
452
write_constant(data->helper->in, "\n");
453
+ /*
454
+ * remote-helpers that advertise the bidi-import capability are required to
455
+ * buffer the complete batch of import commands until this newline before
456
+ * sending data to fast-import.
457
+ * These helpers read back data from fast-import on their stdin, which could
458
+ * be mixed with import commands, otherwise.
459
+ */
460
461
if (finish_command(&fastimport))
462
die("Error while running fast-import");
444
- free(fastimport.argv);
445
- fastimport.argv = NULL;
463
+ argv_array_free_detached(fastimport.argv);
464
465
/*
466
* The fast-import stream of a remote helper that advertises