diff --git a/Documentation/config/transfer.adoc b/Documentation/config/transfer.adoc index f1ce50f4a6..811456f1bf 100644 --- a/Documentation/config/transfer.adoc +++ b/Documentation/config/transfer.adoc @@ -1,3 +1,19 @@ +transfer.connectivityCheck:: + Choose which algorithm to use for the connectivity check + performed during object transfer operations such as + linkgit:git-fetch[1] and linkgit:git-receive-pack[1]. + The connectivity check verifies that all objects reachable + from the incoming tips are available locally or, in a partial + clone, promised by a promisor remote. + The variants are as follows: ++ +-- +`full` (default);; + Walk the full object closure of the boundary commits. +-- ++ +Unknown values are treated as `full`, with a warning. + transfer.credentialsInUrl:: A configured URL can contain plaintext credentials in the form `://:@/`. You may want diff --git a/Documentation/rev-list-options.adoc b/Documentation/rev-list-options.adoc index bd9f345690..3979a142a5 100644 --- a/Documentation/rev-list-options.adoc +++ b/Documentation/rev-list-options.adoc @@ -1102,6 +1102,11 @@ It is an error to use `--missing-only` without `--missing=print` or stronger than `--missing=allow-promisor` because it limits the traversal, rather than just silencing errors about missing objects. + +`--connectivity-check=full`:: + (For internal use only.) Used by `check_connected()` to + select the connectivity check algorithm; see + `transfer.connectivityCheck` in linkgit:git-config[1]. endif::git-rev-list[] `--no-walk[=(sorted|unsorted)]`:: diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 0faa833fac..619855f4e4 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -29,6 +29,23 @@ #include "quote.h" #include "strbuf.h" +enum connectivity_check_mode { + CONNECTIVITY_CHECK_FULL, +}; + +struct connectivity_check { + enum connectivity_check_mode mode; +}; + +static void parse_connectivity_check(const char *arg, + struct connectivity_check *check) +{ + if (!strcmp(arg, "full")) + check->mode = CONNECTIVITY_CHECK_FULL; + else + die(_("unknown --connectivity-check mode '%s'"), arg); +} + struct rev_list_info { struct rev_info *revs; int flags; @@ -727,6 +744,7 @@ int cmd_rev_list(int argc, int bisect_find_all = 0; int use_bitmap_index = 0; int filter_provided_objects = 0; + struct connectivity_check connectivity_check = { 0 }; const char *show_progress = NULL; int ret = 0; @@ -769,6 +787,8 @@ int cmd_rev_list(int argc, if (!strcmp(arg, "--exclude-promisor-objects")) { repo->fetch_if_missing = 0; revs.exclude_promisor_objects = 1; + } else if (skip_prefix(arg, "--connectivity-check=", &arg)) { + parse_connectivity_check(arg, &connectivity_check); } else if (skip_prefix(arg, "--missing=", &arg)) { parse_missing_action_value(repo, arg); } else if (!strcmp(arg, "--missing-only")) { @@ -848,6 +868,8 @@ int cmd_rev_list(int argc, if (!strcmp(arg, "--exclude-promisor-objects")) continue; /* already handled above */ + if (starts_with(arg, "--connectivity-check=")) + continue; /* already handled above */ if (skip_prefix(arg, "--missing=", &arg)) continue; /* already handled above */ diff --git a/connected.c b/connected.c index 34045f1032..0147b7d3b3 100644 --- a/connected.c +++ b/connected.c @@ -1,4 +1,5 @@ #include "git-compat-util.h" +#include "config.h" #include "gettext.h" #include "hex.h" #include "odb.h" @@ -66,6 +67,27 @@ static int check_connected_promisor(struct repository *repo, return 1; } +/* + * Fills in the --connectivity-check mode to pass to rev-list. + */ +static void connectivity_check_mode(struct repository *repo, + struct strbuf *mode) +{ + const char *algorithm = NULL; + + if (repo_config_get_string_tmp(repo, + "transfer.connectivitycheck", + &algorithm)) + algorithm = "full"; + if (!strcasecmp(algorithm, "full")) + strbuf_addstr(mode, "full"); + else { + warning(_("unknown transfer.connectivityCheck algorithm '%s', " + "using 'full'"), algorithm); + strbuf_addstr(mode, "full"); + } +} + /* * If we feed all the commits we want to verify to this command * @@ -84,6 +106,7 @@ int check_connected(struct repository *repo, struct child_process rev_list = CHILD_PROCESS_INIT; FILE *rev_list_in; struct check_connected_options defaults = CHECK_CONNECTED_INIT; + struct strbuf mode = STRBUF_INIT; const struct object_id *oid; int err = 0; struct packed_git *new_pack = NULL; @@ -133,6 +156,9 @@ int check_connected(struct repository *repo, if (opt->progress) strvec_pushf(&rev_list.args, "--progress=%s", _("Checking connectivity")); + connectivity_check_mode(repo, &mode); + strvec_pushf(&rev_list.args, "--connectivity-check=%s", mode.buf); + strbuf_release(&mode); rev_list.git_cmd = 1; if (opt->env)