From: Jeff Hostetler <git@xxxxxxxxxxxxxxxxx> Teach fetch to accept --partial-by-size=n and --partial-special arguments and pass them to fetch-patch to request that the server certain blobs from the generated packfile. Signed-off-by: Jeff Hostetler <jeffhost@xxxxxxxxxxxxx> --- builtin/fetch.c | 26 +++++++++++++++++++++++++- connected.c | 3 +++ connected.h | 3 +++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/builtin/fetch.c b/builtin/fetch.c index b5ad09d..3d47107 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -52,6 +52,8 @@ 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 *partial_by_size; +static int partial_special; static int option_parse_recurse_submodules(const struct option *opt, const char *arg, int unset) @@ -141,6 +143,11 @@ static struct option builtin_fetch_options[] = { TRANSPORT_FAMILY_IPV4), OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"), TRANSPORT_FAMILY_IPV6), + OPT_STRING(0, "partial-by-size", &partial_by_size, + N_("size"), + N_("only include blobs smaller than this")), + OPT_BOOL(0, "partial-special", &partial_special, + N_("only include blobs for git special files")), OPT_END() }; @@ -731,6 +738,10 @@ 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; + + if (partial_by_size || partial_special) + opt.allow_partial = 1; fp = fopen(filename, "a"); if (!fp) @@ -742,7 +753,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; } @@ -882,6 +893,9 @@ static int quickfetch(struct ref *ref_map) struct ref *rm = ref_map; struct check_connected_options opt = CHECK_CONNECTED_INIT; + if (partial_by_size || partial_special) + opt.allow_partial = 1; + /* * If we are deepening a shallow clone we already have these * objects reachable. Running rev-list here will return with @@ -1020,6 +1034,10 @@ 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 (partial_by_size) + set_option(transport, TRANS_OPT_PARTIAL_BY_SIZE, partial_by_size); + if (partial_special) + set_option(transport, TRANS_OPT_PARTIAL_SPECIAL, "yes"); return transport; } @@ -1314,6 +1332,12 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, builtin_fetch_options, builtin_fetch_usage, 0); + if (partial_by_size) { + unsigned long s; + if (!git_parse_ulong(partial_by_size, &s)) + die(_("invalid partial-by-size value")); + } + if (deepen_relative) { if (deepen_relative < 0) die(_("Negative depth in --deepen is not supported")); diff --git a/connected.c b/connected.c index 136c2ac..b07cbb5 100644 --- a/connected.c +++ b/connected.c @@ -62,6 +62,9 @@ int check_connected(sha1_iterate_fn fn, void *cb_data, argv_array_pushf(&rev_list.args, "--progress=%s", _("Checking connectivity")); + if (opt->allow_partial) + argv_array_push(&rev_list.args, "--allow-partial"); + rev_list.git_cmd = 1; rev_list.env = opt->env; rev_list.in = -1; diff --git a/connected.h b/connected.h index 4ca325f..756259e 100644 --- a/connected.h +++ b/connected.h @@ -34,6 +34,9 @@ struct check_connected_options { /* If non-zero, show progress as we traverse the objects. */ int progress; + /* A previous partial clone/fetch may have omitted some blobs. */ + int allow_partial; + /* * Insert these variables into the environment of the child process. */ -- 2.7.4