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 <[email protected]>
---
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
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html