git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 4/5] bundle-uri: add support for http(s):// and file://

From
Derrick Stolee via GitGitGadget <gitgitgadget@gmail.com>
Date
Jul 25, 2022, 20:34 UTC
Message-ID
<f6bc3177332e8608d0ba300669853bbad01c3266.1658781277.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1300.git.1658781277.gitgitgadget@gmail.com>
From: Derrick Stolee <derrickstolee@github.com>

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.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
---
 bundle-uri.c                | 70 +++++++++++++++++++++++++++++++++++--
 t/t5558-clone-bundle-uri.sh | 45 ++++++++++++++++++++++++
 2 files changed, 112 insertions(+), 3 deletions(-)
diff --git a/bundle-uri.c b/bundle-uri.c
index b35babc36aa..7086382b186 100644
--- a/bundle-uri.c
+++ b/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", "origin", 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 (skip_prefix(uri, "https:", &out) ||
+	    skip_prefix(uri, "http:", &out))
+		return download_https_uri_to_file(filename, uri);
+
+	if (!skip_prefix(uri, "file://", &out))
+		out = uri;
+
+	/* Copy as a file */
+	return copy_file(filename, out, 0);
 }
 
 static int unbundle_from_file(struct repository *r, const char *file)
diff --git a/t/t5558-clone-bundle-uri.sh b/t/t5558-clone-bundle-uri.sh
index f709bcb729c..ad666a2d28a 100755
--- a/t/t5558-clone-bundle-uri.sh
+++ b/t/t5558-clone-bundle-uri.sh
@@ -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
-- 
gitgitgadget
Previous: Derrick Stolee via GitGitGadgetNext: Josh Steadmon
Message 12 of 36 in “Bundle URIs II: git clone --bundle-uri”
  1. 0/5 Bundle URIs II: git clone --bundle-uriDerrick Stolee via GitGitGadget, Jul 25, 2022
  2. 1/5 remote-curl: add 'get' capabilityDerrick Stolee via GitGitGadget, Jul 25, 2022
  3. Josh SteadmonJul 27, 2022
  4. Ævar Arnfjörð BjarmasonJul 27, 2022
  5. Derrick StoleeAug 1, 2022
  6. Ævar Arnfjörð BjarmasonAug 1, 2022
  7. 2/5 bundle-uri: create basic file-copy logicDerrick Stolee via GitGitGadget, Jul 25, 2022
  8. Josh SteadmonJul 27, 2022
  9. Derrick StoleeAug 1, 2022
  10. 3/5 clone: add --bundle-uri optionDerrick Stolee via GitGitGadget, Jul 25, 2022
  11. 5/5 clone: --bundle-uri cannot be combined with --depthDerrick Stolee via GitGitGadget, Jul 25, 2022
  12. 4/5 bundle-uri: add support for http(s):// and file://Derrick Stolee via GitGitGadget, Jul 25, 2022
  13. Josh SteadmonJul 27, 2022
  14. Derrick StoleeAug 1, 2022
  15. Josh SteadmonJul 27, 2022
  16. Derrick StoleeAug 1, 2022
  17. 0/5 Bundle URIs II: git clone --bundle-uriDerrick Stolee via GitGitGadget, Aug 2, 2022
  18. 1/5 remote-curl: add 'get' capabilityDerrick Stolee via GitGitGadget, Aug 2, 2022
  19. 2/5 bundle-uri: create basic file-copy logicDerrick Stolee via GitGitGadget, Aug 2, 2022
  20. 3/5 clone: add --bundle-uri optionDerrick Stolee via GitGitGadget, Aug 2, 2022
  21. 4/5 bundle-uri: add support for http(s):// and file://Derrick Stolee via GitGitGadget, Aug 2, 2022
  22. Junio C HamanoAug 2, 2022
  23. Derrick StoleeAug 4, 2022
  24. Junio C HamanoAug 4, 2022
  25. 5/5 clone: --bundle-uri cannot be combined with --depthDerrick Stolee via GitGitGadget, Aug 2, 2022
  26. 0/5 Bundle URIs II: git clone --bundle-uriDerrick Stolee via GitGitGadget, Aug 9, 2022
  27. 1/5 remote-curl: add 'get' capabilityDerrick Stolee via GitGitGadget, Aug 9, 2022
  28. 2/5 bundle-uri: create basic file-copy logicDerrick Stolee via GitGitGadget, Aug 9, 2022
  29. 3/5 clone: add --bundle-uri optionDerrick Stolee via GitGitGadget, Aug 9, 2022
  30. Junio C HamanoAug 22, 2022
  31. Derrick StoleeAug 23, 2022
  32. Junio C HamanoAug 24, 2022
  33. 4/5 bundle-uri: add support for http(s):// and file://Derrick Stolee via GitGitGadget, Aug 9, 2022
  34. 4/5 bundle-uri: add support for http(s):// and file://Teng Long, Aug 29, 2022
  35. Derrick StoleeAug 30, 2022
  36. 5/5 clone: --bundle-uri cannot be combined with --depthDerrick Stolee via GitGitGadget, Aug 9, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.