bundle-uri: add support for http(s):// and file://
The previous change created the 'git clone --bundle-uri=<uri>' option. Currently, <uri> must be a filename. Update copy_uri_to_file() to first inspect the URI for an HTTP(S) prefix and use git-remote-https as the way to download the data at that URI. Otherwise, check to see if file:// is present and modify the prefix accordingly. Reviewed-by: Josh Steadmon <steadmon@google.com> Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
5556891961
commit
59c1752ab6
70
bundle-uri.c
70
bundle-uri.c
@ -23,10 +23,74 @@ static int find_temp_filename(struct strbuf *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int copy_uri_to_file(const char *file, const char *uri)
|
||||
static int download_https_uri_to_file(const char *file, const char *uri)
|
||||
{
|
||||
/* File-based URIs only for now. */
|
||||
return copy_file(file, uri, 0);
|
||||
int result = 0;
|
||||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
FILE *child_in = NULL, *child_out = NULL;
|
||||
struct strbuf line = STRBUF_INIT;
|
||||
int found_get = 0;
|
||||
|
||||
strvec_pushl(&cp.args, "git-remote-https", uri, NULL);
|
||||
cp.in = -1;
|
||||
cp.out = -1;
|
||||
|
||||
if (start_command(&cp))
|
||||
return 1;
|
||||
|
||||
child_in = fdopen(cp.in, "w");
|
||||
if (!child_in) {
|
||||
result = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
child_out = fdopen(cp.out, "r");
|
||||
if (!child_out) {
|
||||
result = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fprintf(child_in, "capabilities\n");
|
||||
fflush(child_in);
|
||||
|
||||
while (!strbuf_getline(&line, child_out)) {
|
||||
if (!line.len)
|
||||
break;
|
||||
if (!strcmp(line.buf, "get"))
|
||||
found_get = 1;
|
||||
}
|
||||
strbuf_release(&line);
|
||||
|
||||
if (!found_get) {
|
||||
result = error(_("insufficient capabilities"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fprintf(child_in, "get %s %s\n\n", uri, file);
|
||||
|
||||
cleanup:
|
||||
if (child_in)
|
||||
fclose(child_in);
|
||||
if (finish_command(&cp))
|
||||
return 1;
|
||||
if (child_out)
|
||||
fclose(child_out);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int copy_uri_to_file(const char *filename, const char *uri)
|
||||
{
|
||||
const char *out;
|
||||
|
||||
if (starts_with(uri, "https:") ||
|
||||
starts_with(uri, "http:"))
|
||||
return download_https_uri_to_file(filename, uri);
|
||||
|
||||
if (skip_prefix(uri, "file://", &out))
|
||||
uri = out;
|
||||
|
||||
/* Copy as a file */
|
||||
return copy_file(filename, uri, 0);
|
||||
}
|
||||
|
||||
static int unbundle_from_file(struct repository *r, const char *file)
|
||||
|
@ -33,4 +33,49 @@ test_expect_success 'clone with path bundle' '
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'clone with file:// bundle' '
|
||||
git clone --bundle-uri="file://$(pwd)/clone-from/B.bundle" \
|
||||
clone-from clone-file &&
|
||||
git -C clone-file rev-parse refs/bundles/topic >actual &&
|
||||
git -C clone-from rev-parse topic >expect &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
#########################################################################
|
||||
# HTTP tests begin here
|
||||
|
||||
. "$TEST_DIRECTORY"/lib-httpd.sh
|
||||
start_httpd
|
||||
|
||||
test_expect_success 'fail to fetch from non-existent HTTP URL' '
|
||||
test_when_finished rm -rf test &&
|
||||
git clone --bundle-uri="$HTTPD_URL/does-not-exist" . test 2>err &&
|
||||
grep "failed to download bundle from URI" err
|
||||
'
|
||||
|
||||
test_expect_success 'fail to fetch from non-bundle HTTP URL' '
|
||||
test_when_finished rm -rf test &&
|
||||
echo bogus >"$HTTPD_DOCUMENT_ROOT_PATH/bogus" &&
|
||||
git clone --bundle-uri="$HTTPD_URL/bogus" . test 2>err &&
|
||||
grep "is not a bundle" err
|
||||
'
|
||||
|
||||
test_expect_success 'clone HTTP bundle' '
|
||||
cp clone-from/B.bundle "$HTTPD_DOCUMENT_ROOT_PATH/B.bundle" &&
|
||||
|
||||
git clone --no-local --mirror clone-from \
|
||||
"$HTTPD_DOCUMENT_ROOT_PATH/fetch.git" &&
|
||||
|
||||
git clone --bundle-uri="$HTTPD_URL/B.bundle" \
|
||||
"$HTTPD_URL/smart/fetch.git" clone-http &&
|
||||
git -C clone-http rev-parse refs/bundles/topic >actual &&
|
||||
git -C clone-from rev-parse topic >expect &&
|
||||
test_cmp expect actual &&
|
||||
|
||||
test_config -C clone-http log.excludedecoration refs/bundle/
|
||||
'
|
||||
|
||||
# Do not add tests here unless they use the HTTP server, as they will
|
||||
# not run unless the HTTP dependencies exist.
|
||||
|
||||
test_done
|
||||
|
Loading…
Reference in New Issue
Block a user