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

[PATCH 6/8] fetch: add --resume-pack=<path>

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Feb 5, 2016, 08:57 UTC
Message-ID
<1454662677-15137-7-git-send-email-pclouds@gmail.com>
In-Reply-To
<1454662677-15137-1-git-send-email-pclouds@gmail.com>

This is a low-level option for resumable fetch. You start a resumable fetch with

    git fetch --resume-pack=blah <host>

where "blah" file does not exist. If the fetch is interrupted, "blah" will contain what's been fetched so far. Run the same command again.

On the server side, pack-objects performs the exact same operation to produce full pack again, but it will not send what is already in "blah". pack-objects does check if the skipped part is the same between two sides, in case of configuration change or whatever, and abort early.

On the client side, index-pack feeds itself with what's in "blah", then the input stream from pack-objects. index-pack does strict verification as usual. Even if pack-objects fails to produce a stable pack, index-pack should catch it and complain loudly. If everything goes well, "blah" is removed and a new good pack is put in $GIT_DIR.

Improvement point. We should be able to perform some heavy operations locally before connecting to the server (e.g. produce the skip hash from "blah", or index-pack consuming "blah").

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/fetch-pack.c | 4 ++++
 builtin/fetch.c      | 5 +++++
 remote-curl.c        | 8 +++++++-
 transport.c          | 4 ++++
 transport.h          | 4 ++++
 5 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 9b2a514..996ad30 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -129,6 +129,10 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
 			args.update_shallow = 1;
 			continue;
 		}
+		if (skip_prefix(arg, "--resume-path=", &arg)) {
+			args.resume_path = arg;
+			continue;
+		}
 		usage(fetch_pack_usage);
 	}
 
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 8e74213..34f32c6 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -48,6 +48,7 @@ static const char *recurse_submodules_default;
 static int shown_url = 0;
 static int refmap_alloc, refmap_nr;
 static const char **refmap_array;
+static const char *resume_path;
 
 static int option_parse_recurse_submodules(const struct option *opt,
 				   const char *arg, int unset)
@@ -115,6 +116,8 @@ static struct option builtin_fetch_options[] = {
 	OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
 	OPT_STRING(0, "depth", &depth, N_("depth"),
 		   N_("deepen history of shallow clone")),
+	OPT_FILENAME(0, "resume-pack", &resume_path,
+		     N_("perform resumable fetch on the given pack")),
 	{ OPTION_SET_INT, 0, "unshallow", &unshallow, NULL,
 		   N_("convert to a complete repository"),
 		   PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1 },
@@ -872,6 +875,8 @@ static struct transport *prepare_transport(struct remote *remote)
 		set_option(transport, TRANS_OPT_DEPTH, depth);
 	if (update_shallow)
 		set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
+	if (resume_path)
+		set_option(transport, TRANS_OPT_RESUME_PATH, resume_path);
 	return transport;
 }
 
diff --git a/remote-curl.c b/remote-curl.c
index c704857..36835fb 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -20,6 +20,7 @@ static struct strbuf url = STRBUF_INIT;
 struct options {
 	int verbosity;
 	unsigned long depth;
+	const char *resume_path;
 	unsigned progress : 1,
 		check_self_contained_and_connected : 1,
 		cloning : 1,
@@ -119,6 +120,9 @@ static int set_option(const char *name, const char *value)
 		else
 			return -1;
 		return 0;
+	} else if (!strcmp(name, "resume-path")) {
+		options.resume_path = xstrdup(value);
+		return 0;
 	} else {
 		return 1 /* unsupported */;
 	}
@@ -727,7 +731,7 @@ static int fetch_git(struct discovery *heads,
 	struct strbuf preamble = STRBUF_INIT;
 	char *depth_arg = NULL;
 	int argc = 0, i, err;
-	const char *argv[17];
+	const char *argv[18];
 
 	argv[argc++] = "fetch-pack";
 	argv[argc++] = "--stateless-rpc";
@@ -755,6 +759,8 @@ static int fetch_git(struct discovery *heads,
 		depth_arg = strbuf_detach(&buf, NULL);
 		argv[argc++] = depth_arg;
 	}
+	if (options.resume_path)
+		argv[argc++] = xstrfmt("--resume-path=%s", options.resume_path);
 	argv[argc++] = url.buf;
 	argv[argc++] = NULL;
 
diff --git a/transport.c b/transport.c
index 67f3666..6378bed 100644
--- a/transport.c
+++ b/transport.c
@@ -467,6 +467,9 @@ static int set_git_option(struct git_transport_options *opts,
 	} else if (!strcmp(name, TRANS_OPT_UPDATE_SHALLOW)) {
 		opts->update_shallow = !!value;
 		return 0;
+	} else if (!strcmp(name, TRANS_OPT_RESUME_PATH)) {
+		opts->resume_path = value;
+		return 0;
 	} else if (!strcmp(name, TRANS_OPT_DEPTH)) {
 		if (!value)
 			opts->depth = 0;
@@ -534,6 +537,7 @@ static int fetch_refs_via_pack(struct transport *transport,
 		data->options.check_self_contained_and_connected;
 	args.cloning = transport->cloning;
 	args.update_shallow = data->options.update_shallow;
+	args.resume_path = data->options.resume_path;
 
 	if (!data->got_remote_heads) {
 		connect_setup(transport, 0, 0);
diff --git a/transport.h b/transport.h
index 8ebaaf2..765e4e5 100644
--- a/transport.h
+++ b/transport.h
@@ -16,6 +16,7 @@ struct git_transport_options {
 	const char *uploadpack;
 	const char *receivepack;
 	struct push_cas_option *cas;
+	const char *resume_path;
 };
 
 struct transport {
@@ -180,6 +181,9 @@ int transport_restrict_protocols(void);
 /* Send push certificates */
 #define TRANS_OPT_PUSH_CERT "pushcert"
 
+/* Resumable fetch */
+#define TRANS_OPT_RESUME_PATH "resume-path"
+
 /**
  * Returns 0 if the option was used, non-zero otherwise. Prints a
  * message to stderr if the option is not used.
-- 
2.7.0.377.g4cd97dd
Previous: Eric SunshineNext: Nguyễn Thái Ngọc Duy
Message 14 of 22 in “Resumable clone revisited, proof of concept”
  1. 0/8 Resumable clone revisited, proof of conceptNguyễn Thái Ngọc Duy, Feb 5, 2016
  2. 1/8 pack-objects: add --skip and --skip-hashNguyễn Thái Ngọc Duy, Feb 5, 2016
  3. Johannes SchindelinFeb 5, 2016
  4. 2/8 pack-objects: produce a stable pack when --skip is givenNguyễn Thái Ngọc Duy, Feb 5, 2016
  5. Junio C HamanoFeb 5, 2016
  6. Duy NguyenFeb 5, 2016
  7. Junio C HamanoFeb 6, 2016
  8. Duy NguyenFeb 8, 2016
  9. 3/8 index-pack: add --append-pack=<path>Nguyễn Thái Ngọc Duy, Feb 5, 2016
  10. 4/8 upload-pack: new capability to pass --skip* to pack-objectsNguyễn Thái Ngọc Duy, Feb 5, 2016
  11. Johannes SchindelinFeb 5, 2016
  12. 5/8 fetch-pack.c: send "skip" line to pack-objectsNguyễn Thái Ngọc Duy, Feb 5, 2016
  13. Eric SunshineFeb 7, 2016
  14. 6/8 fetch: add --resume-pack=<path>Nguyễn Thái Ngọc Duy, Feb 5, 2016
  15. 7/8 index-pack: --append-pack implies --strictNguyễn Thái Ngọc Duy, Feb 5, 2016
  16. Eric SunshineFeb 7, 2016
  17. 8/8 one ugly test to verify basic functionalityNguyễn Thái Ngọc Duy, Feb 5, 2016
  18. Elia PintoFeb 5, 2016
  19. Duy NguyenFeb 5, 2016
  20. Elia PintoFeb 5, 2016
  21. Johannes SchindelinFeb 5, 2016
  22. Elia PintoFeb 5, 2016

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.