Add support for "import" helper command

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>
maint
Daniel Barkalow 2009-11-18 02:42:27 +01:00 committed by Junio C Hamano
parent 87422439d1
commit e65e91ed4a
2 changed files with 62 additions and 0 deletions

View 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
-------------------


View 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;
}