Code

Merge branch 'maint'
[git.git] / transport-helper.c
index dd8dd2c1aebb94b06b6a118d88f4a78ac6cefe45..4eab844d4abfa29ce53b6245a5821ee7be03641b 100644 (file)
@@ -23,6 +23,8 @@ struct helper_data {
                push : 1,
                connect : 1,
                no_disconnect_req : 1;
+       char *export_marks;
+       char *import_marks;
        /* These go from remote name (as in "list") to private name */
        struct refspec *refspecs;
        int refspec_nr;
@@ -181,9 +183,19 @@ static struct child_process *get_helper(struct transport *transport)
                        ALLOC_GROW(refspecs,
                                   refspec_nr + 1,
                                   refspec_alloc);
-                       refspecs[refspec_nr++] = strdup(buf.buf + strlen("refspec "));
+                       refspecs[refspec_nr++] = strdup(capname + strlen("refspec "));
                } else if (!strcmp(capname, "connect")) {
                        data->connect = 1;
+               } else if (!prefixcmp(capname, "export-marks ")) {
+                       struct strbuf arg = STRBUF_INIT;
+                       strbuf_addstr(&arg, "--export-marks=");
+                       strbuf_addstr(&arg, capname + strlen("export-marks "));
+                       data->export_marks = strbuf_detach(&arg, NULL);
+               } else if (!prefixcmp(capname, "import-marks")) {
+                       struct strbuf arg = STRBUF_INIT;
+                       strbuf_addstr(&arg, "--import-marks=");
+                       strbuf_addstr(&arg, capname + strlen("import-marks "));
+                       data->import_marks = strbuf_detach(&arg, NULL);
                } else if (mandatory) {
                        die("Unknown mandatory capability %s. This remote "
                            "helper probably needs newer version of Git.\n",
@@ -209,6 +221,7 @@ static int disconnect_helper(struct transport *transport)
 {
        struct helper_data *data = transport->data;
        struct strbuf buf = STRBUF_INIT;
+       int res = 0;
 
        if (data->helper) {
                if (debug)
@@ -220,13 +233,13 @@ static int disconnect_helper(struct transport *transport)
                close(data->helper->in);
                close(data->helper->out);
                fclose(data->out);
-               finish_command(data->helper);
+               res = finish_command(data->helper);
                free((char *)data->helper->argv[0]);
                free(data->helper->argv);
                free(data->helper);
                data->helper = NULL;
        }
-       return 0;
+       return res;
 }
 
 static const char *unsupported_options[] = {
@@ -304,12 +317,13 @@ static void standard_options(struct transport *t)
 
 static int release_helper(struct transport *transport)
 {
+       int res = 0;
        struct helper_data *data = transport->data;
        free_refspec(data->refspec_nr, data->refspecs);
        data->refspecs = NULL;
-       disconnect_helper(transport);
+       res = disconnect_helper(transport);
        free(transport->data);
-       return 0;
+       return res;
 }
 
 static int fetch_with_fetch(struct transport *transport,
@@ -367,10 +381,9 @@ static int get_importer(struct transport *transport, struct child_process *fasti
 
 static int get_exporter(struct transport *transport,
                        struct child_process *fastexport,
-                       const char *export_marks,
-                       const char *import_marks,
                        struct string_list *revlist_args)
 {
+       struct helper_data *data = transport->data;
        struct child_process *helper = get_helper(transport);
        int argc = 0, i;
        memset(fastexport, 0, sizeof(*fastexport));
@@ -378,12 +391,13 @@ static int get_exporter(struct transport *transport,
        /* we need to duplicate helper->in because we want to use it after
         * fastexport is done with it. */
        fastexport->out = dup(helper->in);
-       fastexport->argv = xcalloc(4 + revlist_args->nr, sizeof(*fastexport->argv));
+       fastexport->argv = xcalloc(5 + revlist_args->nr, sizeof(*fastexport->argv));
        fastexport->argv[argc++] = "fast-export";
-       if (export_marks)
-               fastexport->argv[argc++] = export_marks;
-       if (import_marks)
-               fastexport->argv[argc++] = import_marks;
+       fastexport->argv[argc++] = "--use-done-feature";
+       if (data->export_marks)
+               fastexport->argv[argc++] = data->export_marks;
+       if (data->import_marks)
+               fastexport->argv[argc++] = data->import_marks;
 
        for (i = 0; i < revlist_args->nr; i++)
                fastexport->argv[argc++] = revlist_args->items[i].string;
@@ -415,8 +429,11 @@ static int fetch_with_import(struct transport *transport,
                sendline(data, &buf);
                strbuf_reset(&buf);
        }
-       disconnect_helper(transport);
-       finish_command(&fastimport);
+
+       write_constant(data->helper->in, "\n");
+
+       if (finish_command(&fastimport))
+               die("Error while running fast-import");
        free(fastimport.argv);
        fastimport.argv = NULL;
 
@@ -707,7 +724,6 @@ static int push_refs_with_export(struct transport *transport,
        struct ref *ref;
        struct child_process *helper, exporter;
        struct helper_data *data = transport->data;
-       char *export_marks = NULL, *import_marks = NULL;
        struct string_list revlist_args = STRING_LIST_INIT_NODUP;
        struct strbuf buf = STRBUF_INIT;
 
@@ -715,26 +731,6 @@ static int push_refs_with_export(struct transport *transport,
 
        write_constant(helper->in, "export\n");
 
-       recvline(data, &buf);
-       if (debug)
-               fprintf(stderr, "Debug: Got export_marks '%s'\n", buf.buf);
-       if (buf.len) {
-               struct strbuf arg = STRBUF_INIT;
-               strbuf_addstr(&arg, "--export-marks=");
-               strbuf_addbuf(&arg, &buf);
-               export_marks = strbuf_detach(&arg, NULL);
-       }
-
-       recvline(data, &buf);
-       if (debug)
-               fprintf(stderr, "Debug: Got import_marks '%s'\n", buf.buf);
-       if (buf.len) {
-               struct strbuf arg = STRBUF_INIT;
-               strbuf_addstr(&arg, "--import-marks=");
-               strbuf_addbuf(&arg, &buf);
-               import_marks = strbuf_detach(&arg, NULL);
-       }
-
        strbuf_reset(&buf);
 
        for (ref = remote_refs; ref; ref = ref->next) {
@@ -750,18 +746,21 @@ static int push_refs_with_export(struct transport *transport,
                }
                free(private);
 
+               if (ref->deletion) {
+                       die("remote-helpers do not support ref deletion");
+               }
+
                if (ref->peer_ref)
                        string_list_append(&revlist_args, ref->peer_ref->name);
 
        }
 
-       if (get_exporter(transport, &exporter,
-                        export_marks, import_marks, &revlist_args))
+       if (get_exporter(transport, &exporter, &revlist_args))
                die("Couldn't run fast-export");
 
-       data->no_disconnect_req = 1;
-       finish_command(&exporter);
-       disconnect_helper(transport);
+       if (finish_command(&exporter))
+               die("Error while running fast-export");
+       push_update_refs_status(data, remote_refs);
        return 0;
 }