Skip to content

Commit bdee7b3

Browse files
jltoblergitster
authored andcommitted
builtin/receive-pack: stage incoming objects via ODB transactions
Objects received by git-receive-pack(1) are quarantined in a temporary "incoming" directory and migrated into the object database prior to the reference updates. The quarantine is currently managed through `tmp_objdir` directly. In a pluggable ODB future, how exactly an object gets written to a transaction may vary for a given ODB source. Refactor git-receive-pack(1) to use the ODB transaction interfaces to manage the object staging area in a more agnostic manner accordingly. Note that the ODB transaction is now responsible for managing the primary and alternate ODBs for the repository. One small change as a result is that the temporary directory is now applied as the primary ODB in the main process instead of an alternate. This does not change anything for git-receive-pack(1) though because it only needs access to the newly written objects and doesn't care how exactly it is set up. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 6c24256 commit bdee7b3

1 file changed

Lines changed: 35 additions & 33 deletions

File tree

builtin/receive-pack.c

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
#include "sigchain.h"
3838
#include "string-list.h"
3939
#include "strvec.h"
40-
#include "tmp-objdir.h"
4140
#include "trace.h"
4241
#include "trace2.h"
4342
#include "version.h"
@@ -112,8 +111,6 @@ static enum {
112111
} use_keepalive;
113112
static int keepalive_in_sec = 5;
114113

115-
static struct tmp_objdir *tmp_objdir;
116-
117114
static struct proc_receive_ref {
118115
unsigned int want_add:1,
119116
want_delete:1,
@@ -926,6 +923,7 @@ static void receive_hook_feed_state_free(void *data)
926923
static int run_receive_hook(struct command *commands,
927924
const char *hook_name,
928925
int skip_broken,
926+
struct odb_transaction *transaction,
929927
const struct string_list *push_options)
930928
{
931929
struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
@@ -959,8 +957,8 @@ static int run_receive_hook(struct command *commands,
959957
strvec_push(&opt.env, "GIT_PUSH_OPTION_COUNT");
960958
}
961959

962-
if (tmp_objdir)
963-
strvec_pushv(&opt.env, tmp_objdir_env(tmp_objdir));
960+
if (transaction)
961+
odb_transaction_env(transaction, &opt.env);
964962

965963
prepare_push_cert_sha1(&opt);
966964

@@ -1789,24 +1787,30 @@ static const struct object_id *command_singleton_iterator(void *cb_data)
17891787
}
17901788

17911789
static void set_connectivity_errors(struct command *commands,
1792-
struct shallow_info *si)
1790+
struct shallow_info *si,
1791+
struct odb_transaction *transaction)
17931792
{
17941793
struct command *cmd;
17951794

17961795
for (cmd = commands; cmd; cmd = cmd->next) {
17971796
struct command *singleton = cmd;
17981797
struct check_connected_options opt = CHECK_CONNECTED_INIT;
1798+
struct strvec env = STRVEC_INIT;
17991799

18001800
if (shallow_update && si->shallow_ref[cmd->index])
18011801
/* to be checked in update_shallow_ref() */
18021802
continue;
18031803

1804-
opt.env = tmp_objdir_env(tmp_objdir);
1804+
odb_transaction_env(transaction, &env);
1805+
opt.env = env.v;
1806+
18051807
if (!check_connected(command_singleton_iterator, &singleton,
18061808
&opt))
18071809
continue;
18081810

18091811
cmd->error_string = "missing necessary objects";
1812+
1813+
strvec_clear(&env);
18101814
}
18111815
}
18121816

@@ -2027,6 +2031,7 @@ static void execute_commands_atomic(struct command *commands,
20272031
static void execute_commands(struct command *commands,
20282032
const char *unpacker_error,
20292033
struct shallow_info *si,
2034+
struct odb_transaction *transaction,
20302035
const struct string_list *push_options)
20312036
{
20322037
struct check_connected_options opt = CHECK_CONNECTED_INIT;
@@ -2043,6 +2048,8 @@ static void execute_commands(struct command *commands,
20432048
}
20442049

20452050
if (!skip_connectivity_check) {
2051+
struct strvec env = STRVEC_INIT;
2052+
20462053
if (use_sideband) {
20472054
memset(&muxer, 0, sizeof(muxer));
20482055
muxer.proc = copy_to_sideband;
@@ -2056,14 +2063,17 @@ static void execute_commands(struct command *commands,
20562063
data.si = si;
20572064
opt.err_fd = err_fd;
20582065
opt.progress = err_fd && !quiet;
2059-
opt.env = tmp_objdir_env(tmp_objdir);
2066+
odb_transaction_env(transaction, &env);
2067+
opt.env = env.v;
20602068
opt.exclude_hidden_refs_section = "receive";
20612069

20622070
if (check_connected(iterate_receive_command_list, &data, &opt))
2063-
set_connectivity_errors(commands, si);
2071+
set_connectivity_errors(commands, si, transaction);
20642072

20652073
if (use_sideband)
20662074
finish_async(&muxer);
2075+
2076+
strvec_clear(&env);
20672077
}
20682078

20692079
reject_updates_to_hidden(commands);
@@ -2084,7 +2094,7 @@ static void execute_commands(struct command *commands,
20842094
}
20852095
}
20862096

2087-
if (run_receive_hook(commands, "pre-receive", 0, push_options)) {
2097+
if (run_receive_hook(commands, "pre-receive", 0, transaction, push_options)) {
20882098
for (cmd = commands; cmd; cmd = cmd->next) {
20892099
if (!cmd->error_string)
20902100
cmd->error_string = "pre-receive hook declined";
@@ -2105,14 +2115,13 @@ static void execute_commands(struct command *commands,
21052115
* Now we'll start writing out refs, which means the objects need
21062116
* to be in their final positions so that other processes can see them.
21072117
*/
2108-
if (tmp_objdir_migrate(tmp_objdir) < 0) {
2118+
if (odb_transaction_commit(transaction)) {
21092119
for (cmd = commands; cmd; cmd = cmd->next) {
21102120
if (!cmd->error_string)
21112121
cmd->error_string = "unable to migrate objects to permanent storage";
21122122
}
21132123
return;
21142124
}
2115-
tmp_objdir = NULL;
21162125

21172126
check_aliased_updates(commands);
21182127

@@ -2325,7 +2334,8 @@ static void push_header_arg(struct strvec *args, struct pack_header *hdr)
23252334
ntohl(hdr->hdr_version), ntohl(hdr->hdr_entries));
23262335
}
23272336

2328-
static const char *unpack(int err_fd, struct shallow_info *si)
2337+
static const char *unpack(int err_fd, struct shallow_info *si,
2338+
struct odb_transaction *transaction)
23292339
{
23302340
struct pack_header hdr;
23312341
const char *hdr_err;
@@ -2350,20 +2360,7 @@ static const char *unpack(int err_fd, struct shallow_info *si)
23502360
strvec_push(&child.args, alt_shallow_file);
23512361
}
23522362

2353-
tmp_objdir = tmp_objdir_create(the_repository, "incoming");
2354-
if (!tmp_objdir) {
2355-
if (err_fd > 0)
2356-
close(err_fd);
2357-
return "unable to create temporary object directory";
2358-
}
2359-
strvec_pushv(&child.env, tmp_objdir_env(tmp_objdir));
2360-
2361-
/*
2362-
* Normally we just pass the tmp_objdir environment to the child
2363-
* processes that do the heavy lifting, but we may need to see these
2364-
* objects ourselves to set up shallow information.
2365-
*/
2366-
tmp_objdir_add_as_alternate(tmp_objdir);
2363+
odb_transaction_env(transaction, &child.env);
23672364

23682365
if (ntohl(hdr.hdr_entries) < unpack_limit) {
23692366
strvec_push(&child.args, "unpack-objects");
@@ -2430,13 +2427,14 @@ static const char *unpack(int err_fd, struct shallow_info *si)
24302427
return NULL;
24312428
}
24322429

2433-
static const char *unpack_with_sideband(struct shallow_info *si)
2430+
static const char *unpack_with_sideband(struct shallow_info *si,
2431+
struct odb_transaction *transaction)
24342432
{
24352433
struct async muxer;
24362434
const char *ret;
24372435

24382436
if (!use_sideband)
2439-
return unpack(0, si);
2437+
return unpack(0, si, transaction);
24402438

24412439
use_keepalive = KEEPALIVE_AFTER_NUL;
24422440
memset(&muxer, 0, sizeof(muxer));
@@ -2445,7 +2443,7 @@ static const char *unpack_with_sideband(struct shallow_info *si)
24452443
if (start_async(&muxer))
24462444
return NULL;
24472445

2448-
ret = unpack(muxer.in, si);
2446+
ret = unpack(muxer.in, si, transaction);
24492447

24502448
finish_async(&muxer);
24512449
return ret;
@@ -2622,6 +2620,7 @@ int cmd_receive_pack(int argc,
26222620
struct oid_array ref = OID_ARRAY_INIT;
26232621
struct shallow_info si;
26242622
struct packet_reader reader;
2623+
struct odb_transaction *transaction = NULL;
26252624

26262625
struct option options[] = {
26272626
OPT__QUIET(&quiet, N_("quiet")),
@@ -2706,11 +2705,14 @@ int cmd_receive_pack(int argc,
27062705
if (!si.nr_ours && !si.nr_theirs)
27072706
shallow_update = 0;
27082707
if (!delete_only(commands)) {
2709-
unpack_status = unpack_with_sideband(&si);
2708+
if (odb_transaction_begin(the_repository->objects, &transaction, ODB_TRANSACTION_RECEIVE))
2709+
unpack_status = "unable to start object transaction";
2710+
else
2711+
unpack_status = unpack_with_sideband(&si, transaction);
27102712
update_shallow_info(commands, &si, &ref);
27112713
}
27122714
use_keepalive = KEEPALIVE_ALWAYS;
2713-
execute_commands(commands, unpack_status, &si,
2715+
execute_commands(commands, unpack_status, &si, transaction,
27142716
&push_options);
27152717
delete_tempfile(&pack_lockfile);
27162718
sigchain_push(SIGPIPE, SIG_IGN);
@@ -2719,7 +2721,7 @@ int cmd_receive_pack(int argc,
27192721
else if (report_status)
27202722
report(commands, unpack_status);
27212723
sigchain_pop(SIGPIPE);
2722-
run_receive_hook(commands, "post-receive", 1,
2724+
run_receive_hook(commands, "post-receive", 1, NULL,
27232725
&push_options);
27242726
run_update_post_hook(commands);
27252727
free_commands(commands);

0 commit comments

Comments
 (0)