`$GIT_URL/info/refs?service=git-receive-pack` requests. See
`--http-backend-info-refs` in linkgit:git-upload-pack[1].
+--skip-connectivity-check::
+ Bypasses the connectivity checks that validate the existence of all
+ objects in the transitive closure of reachable objects. This option is
+ intended for server operators that want to implement their own object
+ connectivity validation outside of Git. This is useful in such cases
+ where the server-side knows additional information about how Git is
+ being used and thus can rely on certain guarantees to more efficiently
+ compute object connectivity that Git itself cannot make. Usage of this
+ option without a reliable external mechanism to ensure full reachable
+ object connectivity risks corrupting the repository and should not be
+ used in the general case.
+
PRE-RECEIVE HOOK
----------------
Before any ref is updated, if $GIT_DIR/hooks/pre-receive file exists
static int auto_update_server_info;
static int auto_gc = 1;
static int reject_thin;
+static int skip_connectivity_check;
static int stateless_rpc;
static const char *service_dir;
static const char *head_name;
return;
}
- if (use_sideband) {
- memset(&muxer, 0, sizeof(muxer));
- muxer.proc = copy_to_sideband;
- muxer.in = -1;
- if (!start_async(&muxer))
- err_fd = muxer.in;
- /* ...else, continue without relaying sideband */
- }
+ if (!skip_connectivity_check) {
+ if (use_sideband) {
+ memset(&muxer, 0, sizeof(muxer));
+ muxer.proc = copy_to_sideband;
+ muxer.in = -1;
+ if (!start_async(&muxer))
+ err_fd = muxer.in;
+ /* ...else, continue without relaying sideband */
+ }
- data.cmds = commands;
- data.si = si;
- opt.err_fd = err_fd;
- opt.progress = err_fd && !quiet;
- opt.env = tmp_objdir_env(tmp_objdir);
- opt.exclude_hidden_refs_section = "receive";
+ data.cmds = commands;
+ data.si = si;
+ opt.err_fd = err_fd;
+ opt.progress = err_fd && !quiet;
+ opt.env = tmp_objdir_env(tmp_objdir);
+ opt.exclude_hidden_refs_section = "receive";
- if (check_connected(iterate_receive_command_list, &data, &opt))
- set_connectivity_errors(commands, si);
+ if (check_connected(iterate_receive_command_list, &data, &opt))
+ set_connectivity_errors(commands, si);
- if (use_sideband)
- finish_async(&muxer);
+ if (use_sideband)
+ finish_async(&muxer);
+ }
reject_updates_to_hidden(commands);
struct option options[] = {
OPT__QUIET(&quiet, N_("quiet")),
+ OPT_HIDDEN_BOOL(0, "skip-connectivity-check", &skip_connectivity_check, NULL),
OPT_HIDDEN_BOOL(0, "stateless-rpc", &stateless_rpc, NULL),
OPT_HIDDEN_BOOL(0, "http-backend-info-refs", &advertise_refs, NULL),
OPT_ALIAS(0, "advertise-refs", "http-backend-info-refs"),
test_must_fail git -C remote.git cat-file -e $(git -C repo rev-parse HEAD)
'
+test_expect_success 'receive-pack missing objects bypasses connectivity check' '
+ test_when_finished rm -rf repo remote.git setup.git &&
+
+ git init repo &&
+ git -C repo commit --allow-empty -m 1 &&
+ git clone --bare repo setup.git &&
+ git -C repo commit --allow-empty -m 2 &&
+
+ # Capture git-send-pack(1) output sent to git-receive-pack(1).
+ git -C repo send-pack ../setup.git --all \
+ --receive-pack="tee ${SQ}$(pwd)/out${SQ} | git-receive-pack" &&
+
+ # Replay captured git-send-pack(1) output on new empty repository.
+ git init --bare remote.git &&
+ git receive-pack --skip-connectivity-check remote.git <out >actual 2>err &&
+
+ test_grep ! "missing necessary objects" actual &&
+ test_must_be_empty err &&
+ git -C remote.git cat-file -e $(git -C repo rev-parse HEAD) &&
+ test_must_fail git -C remote.git rev-list $(git -C repo rev-parse HEAD)
+'
+
test_done