@@ -168,6 +168,9 @@ Supported commands: 'list', 'import'.
Can guarantee that when a clone is requested, the received
pack is self contained and is connected.
+'get'::
+ Can use the 'get' command to download a file from a given URI.
+
If a helper advertises 'connect', Git will use it if possible and
fall back to another capability if the helper requests so when
connecting (see the 'connect' command under COMMANDS).
@@ -418,6 +421,9 @@ Supported if the helper has the "connect" capability.
+
Supported if the helper has the "stateless-connect" capability.
+'get' <uri> <path>::
+ Downloads the file from the given `<uri>` to the given `<path>`.
+
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
@@ -1276,6 +1276,33 @@ static void parse_fetch(struct strbuf *buf)
strbuf_reset(buf);
}
+static void parse_get(struct strbuf *buf)
+{
+ struct http_get_options opts = { 0 };
+ struct strbuf url = STRBUF_INIT;
+ struct strbuf path = STRBUF_INIT;
+ const char *p, *space;
+
+ if (!skip_prefix(buf->buf, "get ", &p))
+ die(_("http transport does not support %s"), buf->buf);
+
+ space = strchr(p, ' ');
+
+ if (!space)
+ die(_("protocol error: expected '<url> <path>', missing space"));
+
+ strbuf_add(&url, p, space - p);
+ strbuf_addstr(&path, space + 1);
+
+ http_get_file(url.buf, path.buf, &opts);
+
+ strbuf_release(&url);
+ strbuf_release(&path);
+ printf("\n");
+ fflush(stdout);
+ strbuf_reset(buf);
+}
+
static int push_dav(int nr_spec, const char **specs)
{
struct child_process child = CHILD_PROCESS_INIT;
@@ -1549,9 +1576,14 @@ int cmd_main(int argc, const char **argv)
printf("unsupported\n");
fflush(stdout);
+ } else if (skip_prefix(buf.buf, "get ", &arg)) {
+ parse_get(&buf);
+ fflush(stdout);
+
} else if (!strcmp(buf.buf, "capabilities")) {
printf("stateless-connect\n");
printf("fetch\n");
+ printf("get\n");
printf("option\n");
printf("push\n");
printf("check-connectivity\n");
new file mode 100755
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+test_description='test fetching files and bundles over HTTP'
+
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-httpd.sh
+start_httpd
+
+test_expect_success 'set up source repo' '
+ git init src &&
+ test_commit -C src one
+'
+
+test_expect_success 'fail to get a file over HTTP' '
+ cat >input <<-EOF &&
+ get $HTTPD_URL/does-not-exist.txt download-failed.txt
+
+ EOF
+ git remote-https "$HTTPD_URL" <input 2>err &&
+ test_path_is_missing download-failed.txt
+'
+
+test_done
@@ -33,7 +33,8 @@ struct helper_data {
check_connectivity : 1,
no_disconnect_req : 1,
no_private_update : 1,
- object_format : 1;
+ object_format : 1,
+ get : 1;
/*
* As an optimization, the transport code may invoke fetch before
@@ -210,6 +211,8 @@ static struct child_process *get_helper(struct transport *transport)
data->no_private_update = 1;
} else if (starts_with(capname, "object-format")) {
data->object_format = 1;
+ } else if (!strcmp(capname, "get")) {
+ data->get = 1;
} else if (mandatory) {
die(_("unknown mandatory capability %s; this remote "
"helper probably needs newer version of Git"),