connected: add transfer.connectivityCheck config

Add the transfer.connectivityCheck configuration option to choose
the algorithm used for the connectivity check.  For now the only
accepted value is "full", which is the existing behavior and the
default.  Unknown values fall back to "full" with a warning, so
that configuration written for a newer version of Git does not
break fetches and pushes; "full" is always a correct check.

check_connected() now always tells its rev-list subprocess which
algorithm to use with an internal --connectivity-check=<mode>
option, which so far only accepts "full".  Passing the mode
explicitly means rev-list knows it is running a connectivity
check, so later optimizations can be limited to that case.

This prepares for an incremental check added in the next commit.

Suggested-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Kristofer Karlsson <krka@spotify.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Kristofer Karlsson authored and Junio C Hamano committed 2026-10-23 08:32:30 -07:00
1 parent d6d2d8557c
commit 9e0207b50b
4 files changed
+69

No files matched your search

+16
View File
@@ -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
`<protocol>://<user>:<password>@<domain>/<path>`. You may want
+5
View File
@@ -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)]`::
+22
View File
@@ -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 */
+26
View File
@@ -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)