builtin/receive-pack: lift global state out of unpack()

In git-receive-pack(1), writing the packfile to the transaction is
handled via `unpack()` which relies on global variables to decide how to
invoke the underlying git-index-pack(1) or git-unpack-objects(1) child
processes. In a subsequent commit, the `unpack()` logic is moved behind
a generic ODB transaction interface to handle writing packfiles and thus
can no longer rely on these globals.

Lift the global state out of `unpack()` by instead storing this state in
a `struct unpack_opts` that gets passed to the function explicitly.

Signed-off-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
main
Justin Tobler 2026-08-20 18:49:36 -05:00 committed by Junio C Hamano
parent c59466d4cf
commit 255f3a7a53
1 changed files with 41 additions and 22 deletions

View File

@ -2330,18 +2330,24 @@ static unsigned int get_unpack_limit(struct repository *repo)
return limit;
}

struct unpack_opts {
const char *fsck_msg_types;
const char *shallow_file;
off_t max_input_size;
int fsck_objects;
int reject_thin;
int err_fd;
int quiet;
};

static const char *unpack(struct odb_transaction *transaction,
const char *shallow_file, int err_fd)
const struct unpack_opts *opts)
{
struct pack_header hdr;
const char *hdr_err;
int status;
struct child_process child = CHILD_PROCESS_INIT;
int fsck_objects = (receive_fsck_objects >= 0
? receive_fsck_objects
: transfer_fsck_objects >= 0
? transfer_fsck_objects
: 0);
int err_fd = opts->err_fd;

hdr_err = parse_pack_header(&hdr);
if (hdr_err) {
@ -2350,9 +2356,9 @@ static const char *unpack(struct odb_transaction *transaction,
return hdr_err;
}

if (shallow_file) {
if (opts->shallow_file) {
strvec_push(&child.args, "--shallow-file");
strvec_push(&child.args, shallow_file);
strvec_push(&child.args, opts->shallow_file);
}

odb_transaction_env(transaction, &child.env);
@ -2360,14 +2366,14 @@ static const char *unpack(struct odb_transaction *transaction,
if (ntohl(hdr.hdr_entries) < get_unpack_limit(the_repository)) {
strvec_push(&child.args, "unpack-objects");
push_header_arg(&child.args, &hdr);
if (quiet)
if (opts->quiet)
strvec_push(&child.args, "-q");
if (fsck_objects)
if (opts->fsck_objects)
strvec_pushf(&child.args, "--strict%s",
fsck_msg_types.buf);
if (max_input_size)
opts->fsck_msg_types);
if (opts->max_input_size)
strvec_pushf(&child.args, "--max-input-size=%"PRIuMAX,
(uintmax_t)max_input_size);
(uintmax_t)opts->max_input_size);
child.no_stdout = 1;
child.err = err_fd;
child.git_cmd = 1;
@ -2388,18 +2394,18 @@ static const char *unpack(struct odb_transaction *transaction,
(uintmax_t)getpid(),
hostname);

if (!quiet && err_fd)
if (!opts->quiet && err_fd)
strvec_push(&child.args, "--show-resolving-progress");
if (use_sideband)
if (err_fd)
strvec_push(&child.args, "--report-end-of-input");
if (fsck_objects)
if (opts->fsck_objects)
strvec_pushf(&child.args, "--strict%s",
fsck_msg_types.buf);
if (!reject_thin)
opts->fsck_msg_types);
if (!opts->reject_thin)
strvec_push(&child.args, "--fix-thin");
if (max_input_size)
if (opts->max_input_size)
strvec_pushf(&child.args, "--max-input-size=%"PRIuMAX,
(uintmax_t)max_input_size);
(uintmax_t)opts->max_input_size);
child.out = -1;
child.err = err_fd;
child.git_cmd = 1;
@ -2431,11 +2437,23 @@ static const char *unpack(struct odb_transaction *transaction,
static const char *unpack_with_sideband(struct odb_transaction *transaction,
const char *shallow_file)
{
struct unpack_opts opts = {
.fsck_objects = (receive_fsck_objects >= 0
? receive_fsck_objects
: transfer_fsck_objects >= 0
? transfer_fsck_objects
: 0),
.fsck_msg_types = fsck_msg_types.buf,
.max_input_size = max_input_size,
.shallow_file = shallow_file,
.reject_thin = reject_thin,
.quiet = quiet,
};
struct async muxer;
const char *ret;

if (!use_sideband)
return unpack(transaction, shallow_file, 0);
return unpack(transaction, &opts);

use_keepalive = KEEPALIVE_AFTER_NUL;
memset(&muxer, 0, sizeof(muxer));
@ -2444,7 +2462,8 @@ static const char *unpack_with_sideband(struct odb_transaction *transaction,
if (start_async(&muxer))
return NULL;

ret = unpack(transaction, shallow_file, muxer.in);
opts.err_fd = muxer.in;
ret = unpack(transaction, &opts);

finish_async(&muxer);
return ret;