Add support for "import" helper command
authorDaniel Barkalow <barkalow@iabervon.org>
Wed, 18 Nov 2009 01:42:27 +0000 (02:42 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 18 Nov 2009 05:45:44 +0000 (21:45 -0800)
This command, supported if the "import" capability is advertized,
allows a helper to support fetching by outputting a git-fast-import
stream.

If both "fetch" and "import" are advertized, git itself will use
"fetch" (although other users may use "import" in this case).

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Sverre Rabbelier <srabbelier@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-remote-helpers.txt
transport-helper.c

index 173ee232f2cd24231ab95e3337da555be27a4746..e9aa67e757ac777f10a684258366002dd932ada8 100644 (file)
@@ -43,6 +43,13 @@ Commands are given by the caller on the helper's standard input, one per line.
 +
 Supported if the helper has the "fetch" capability.
 
+'import' <name>::
+       Produces a fast-import stream which imports the current value
+       of the named ref. It may additionally import other refs as
+       needed to construct the history efficiently.
++
+Supported if the helper has the "import" capability.
+
 If a fatal error occurs, the program writes the error message to
 stderr and exits. The caller should expect that a suitable error
 message has been printed if the child closes the connection without
@@ -57,6 +64,9 @@ CAPABILITIES
 'fetch'::
        This helper supports the 'fetch' command.
 
+'import'::
+       This helper supports the 'import' command.
+
 REF LIST ATTRIBUTES
 -------------------
 
index 53d8f08ee9cd3ead105953940d7ad42028b6ab4a..82caaaead6666eecaceedfbaa486dae4901a80a5 100644 (file)
@@ -11,6 +11,7 @@ struct helper_data
        const char *name;
        struct child_process *helper;
        unsigned fetch : 1;
+       unsigned import : 1;
 };
 
 static struct child_process *get_helper(struct transport *transport)
@@ -48,6 +49,8 @@ static struct child_process *get_helper(struct transport *transport)
                        break;
                if (!strcmp(buf.buf, "fetch"))
                        data->fetch = 1;
+               if (!strcmp(buf.buf, "import"))
+                       data->import = 1;
        }
        return data->helper;
 }
@@ -98,6 +101,52 @@ static int fetch_with_fetch(struct transport *transport,
        return 0;
 }
 
+static int get_importer(struct transport *transport, struct child_process *fastimport)
+{
+       struct child_process *helper = get_helper(transport);
+       memset(fastimport, 0, sizeof(*fastimport));
+       fastimport->in = helper->out;
+       fastimport->argv = xcalloc(5, sizeof(*fastimport->argv));
+       fastimport->argv[0] = "fast-import";
+       fastimport->argv[1] = "--quiet";
+
+       fastimport->git_cmd = 1;
+       return start_command(fastimport);
+}
+
+static int fetch_with_import(struct transport *transport,
+                            int nr_heads, struct ref **to_fetch)
+{
+       struct child_process fastimport;
+       struct child_process *helper = get_helper(transport);
+       int i;
+       struct ref *posn;
+       struct strbuf buf = STRBUF_INIT;
+
+       if (get_importer(transport, &fastimport))
+               die("Couldn't run fast-import");
+
+       for (i = 0; i < nr_heads; i++) {
+               posn = to_fetch[i];
+               if (posn->status & REF_STATUS_UPTODATE)
+                       continue;
+
+               strbuf_addf(&buf, "import %s\n", posn->name);
+               write_in_full(helper->in, buf.buf, buf.len);
+               strbuf_reset(&buf);
+       }
+       disconnect_helper(transport);
+       finish_command(&fastimport);
+
+       for (i = 0; i < nr_heads; i++) {
+               posn = to_fetch[i];
+               if (posn->status & REF_STATUS_UPTODATE)
+                       continue;
+               read_ref(posn->name, posn->old_sha1);
+       }
+       return 0;
+}
+
 static int fetch(struct transport *transport,
                 int nr_heads, struct ref **to_fetch)
 {
@@ -115,6 +164,9 @@ static int fetch(struct transport *transport,
        if (data->fetch)
                return fetch_with_fetch(transport, nr_heads, to_fetch);
 
+       if (data->import)
+               return fetch_with_import(transport, nr_heads, to_fetch);
+
        return -1;
 }