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

[PATCH 04/14] fetch: add object filtering for partial fetch

From
JHJeff Hostetler <git@jeffhostetler.com>
Date
Nov 2, 2017, 20:31 UTC
Message-ID
<20171102203129.59417-5-git@jeffhostetler.com>
In-Reply-To
<20171102203129.59417-1-git@jeffhostetler.com>
From: Jeff Hostetler <jeffhost@microsoft.com>

Teach fetch to use the list-objects filtering parameters to allow a "partial fetch" following a "partial clone".

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
---
 builtin/fetch.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 1 deletion(-)
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 1b1f039..150ca0a 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -18,6 +18,7 @@
 #include "argv-array.h"
 #include "utf8.h"
 #include "packfile.h"
+#include "list-objects-filter-options.h"
 
 static const char * const builtin_fetch_usage[] = {
 	N_("git fetch [<options>] [<repository> [<refspec>...]]"),
@@ -55,6 +56,7 @@ static int recurse_submodules_default = RECURSE_SUBMODULES_ON_DEMAND;
 static int shown_url = 0;
 static int refmap_alloc, refmap_nr;
 static const char **refmap_array;
+static struct list_objects_filter_options filter_options;
 
 static int git_fetch_config(const char *k, const char *v, void *cb)
 {
@@ -160,6 +162,7 @@ static struct option builtin_fetch_options[] = {
 			TRANSPORT_FAMILY_IPV4),
 	OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
 			TRANSPORT_FAMILY_IPV6),
+	OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
 	OPT_END()
 };
 
@@ -754,6 +757,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
 	const char *filename = dry_run ? "/dev/null" : git_path_fetch_head();
 	int want_status;
 	int summary_width = transport_summary_width(ref_map);
+	struct check_connected_options opt = CHECK_CONNECTED_INIT;
 
 	fp = fopen(filename, "a");
 	if (!fp)
@@ -765,7 +769,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
 		url = xstrdup("foreign");
 
 	rm = ref_map;
-	if (check_connected(iterate_ref_map, &rm, NULL)) {
+	if (check_connected(iterate_ref_map, &rm, &opt)) {
 		rc = error(_("%s did not send all necessary objects\n"), url);
 		goto abort;
 	}
@@ -1044,6 +1048,9 @@ static struct transport *prepare_transport(struct remote *remote, int deepen)
 		set_option(transport, TRANS_OPT_DEEPEN_RELATIVE, "yes");
 	if (update_shallow)
 		set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
+	if (filter_options.choice)
+		set_option(transport, TRANS_OPT_LIST_OBJECTS_FILTER,
+			   filter_options.raw_value);
 	return transport;
 }
 
@@ -1242,6 +1249,20 @@ static int fetch_multiple(struct string_list *list)
 	int i, result = 0;
 	struct argv_array argv = ARGV_ARRAY_INIT;
 
+	if (filter_options.choice) {
+		/*
+		 * We currently only support partial-fetches to the remote
+		 * used for the partial-clone because we only support 1
+		 * promisor remote, so we DO NOT allow explicit command
+		 * line filter arguments.
+		 *
+		 * Note that the loop below will spawn background fetches
+		 * for each remote and one of them MAY INHERIT the proper
+		 * partial-fetch settings, so everything is consistent.
+		 */
+		die(_("partial-fetch is not supported on multiple remotes"));
+	}
+
 	if (!append && !dry_run) {
 		int errcode = truncate_fetch_head();
 		if (errcode)
@@ -1267,6 +1288,46 @@ static int fetch_multiple(struct string_list *list)
 	return result;
 }
 
+static inline void partial_fetch_one_setup(struct remote *remote)
+{
+#if 0 /* TODO */
+	if (filter_options.choice) {
+		/*
+		 * A partial-fetch was explicitly requested.
+		 *
+		 * If this is the first partial-* command on
+		 * this repo, we must register the partial
+		 * settings in the repository extension.
+		 *
+		 * If this follows a previous partial-* command
+		 * we must ensure the args are consistent with
+		 * the existing registration (because we don't
+		 * currently support mixing-and-matching).
+		 */
+		partial_clone_utils_register(&filter_options,
+					     remote->name, "fetch");
+		return;
+	}
+
+	if (is_partial_clone_registered() &&
+	    !strcmp(remote->name, repository_format_partial_clone_remote)) {
+		/*
+		 * If a partial-* command has already been used on
+		 * this repo and it was to this remote, we should
+		 * inherit the filter settings used previously.
+		 * That is, if clone omitted very large blobs, then
+		 * fetch should too.
+		 *
+		 * Use the cached filter-spec and create the filter
+		 * settings.
+		 */
+		parse_list_objects_filter(
+			&filter_options,
+			repository_format_partial_clone_filter);
+	}
+#endif
+}
+
 static int fetch_one(struct remote *remote, int argc, const char **argv)
 {
 	static const char **refs = NULL;
@@ -1278,6 +1339,9 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
 		die(_("No remote repository specified.  Please, specify either a URL or a\n"
 		    "remote name from which new revisions should be fetched."));
 
+	partial_fetch_one_setup(remote);
+
+
 	gtransport = prepare_transport(remote, 1);
 
 	if (prune < 0) {
-- 
2.9.3
Previous: Jeff HostetlerNext: Jonathan Tan
Message 6 of 23 in “WIP Partial clone part 3: clone, fetch, fetch-pack, upload-pack, and tests”
  1. 00/14 WIP Partial clone part 3: clone, fetch, fetch-pack, upload-pack, and testsJeff Hostetler, Nov 2, 2017
  2. 02/14 clone, fetch-pack, index-pack, transport: partial cloneJeff Hostetler, Nov 2, 2017
  3. Jonathan TanNov 3, 2017
  4. Adam DinwoodieNov 8, 2017
  5. Jeff HostetlerNov 16, 2017
  6. 04/14 fetch: add object filtering for partial fetchJeff Hostetler, Nov 2, 2017
  7. Jonathan TanNov 3, 2017
  8. Jeff HostetlerNov 16, 2017
  9. 05/14 remote-curl: add object filtering for partial cloneJeff Hostetler, Nov 2, 2017
  10. 07/14 fetch-pack: test support excluding large blobsJeff Hostetler, Nov 2, 2017
  11. 08/14 fetch: add from_promisor and exclude-promisor-objects parametersJeff Hostetler, Nov 2, 2017
  12. 10/14 t5601: test for partial cloneJeff Hostetler, Nov 2, 2017
  13. 13/14 fetch-pack: restore save_commit_buffer after useJeff Hostetler, Nov 2, 2017
  14. 11/14 t5500: more tests for partial clone and fetchJeff Hostetler, Nov 2, 2017
  15. 14/14 index-pack: silently assume missing objects are promisorJeff Hostetler, Nov 2, 2017
  16. 12/14 unpack-trees: batch fetching of missing blobsJeff Hostetler, Nov 2, 2017
  17. 09/14 t5500: add fetch-pack tests for partial cloneJeff Hostetler, Nov 2, 2017
  18. 06/14 pack-objects: test support for blob filteringJeff Hostetler, Nov 2, 2017
  19. 03/14 fetch: refactor calculation of remote listJeff Hostetler, Nov 2, 2017
  20. 01/14 upload-pack: add object filtering for partial cloneJeff Hostetler, Nov 2, 2017
  21. Jonathan TanNov 2, 2017
  22. Jeff HostetlerNov 3, 2017
  23. Junio C HamanoNov 3, 2017

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.