Skip to content

Commit b7b2157

Browse files
10ne1gitster
authored andcommitted
reference-transaction: use hook API instead of run-command
Convert the reference-transaction hook to the new hook API, so it doesn't need to set up a struct child_process, call find_hook or toggle the pipe signals. The stdin feed callback is processing one ref update per call. I haven't noticed any performance degradation due to this, however we can batch as many we want in each call, to ensure a good pipe throughtput (i.e. the child does not wait after stdin). Helped-by: Emily Shaffer <nasamuffin@google.com> Signed-off-by: Emily Shaffer <emilyshaffer@google.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 9ac9612 commit b7b2157

1 file changed

Lines changed: 52 additions & 50 deletions

File tree

refs.c

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include "iterator.h"
1616
#include "refs.h"
1717
#include "refs/refs-internal.h"
18-
#include "run-command.h"
1918
#include "hook.h"
2019
#include "object-name.h"
2120
#include "odb.h"
@@ -26,7 +25,6 @@
2625
#include "strvec.h"
2726
#include "repo-settings.h"
2827
#include "setup.h"
29-
#include "sigchain.h"
3028
#include "date.h"
3129
#include "commit.h"
3230
#include "wildmatch.h"
@@ -2422,68 +2420,72 @@ static int ref_update_reject_duplicates(struct string_list *refnames,
24222420
return 0;
24232421
}
24242422

2425-
static int run_transaction_hook(struct ref_transaction *transaction,
2426-
const char *state)
2423+
struct transaction_feed_cb_data {
2424+
size_t index;
2425+
struct strbuf buf;
2426+
};
2427+
2428+
static int transaction_hook_feed_stdin(int hook_stdin_fd, void *pp_cb, void *pp_task_cb)
24272429
{
2428-
struct child_process proc = CHILD_PROCESS_INIT;
2429-
struct strbuf buf = STRBUF_INIT;
2430-
const char *hook;
2431-
int ret = 0;
2430+
struct hook_cb_data *hook_cb = pp_cb;
2431+
struct ref_transaction *transaction = hook_cb->options->feed_pipe_ctx;
2432+
struct transaction_feed_cb_data *feed_cb_data = pp_task_cb;
2433+
struct strbuf *buf = &feed_cb_data->buf;
2434+
struct ref_update *update;
2435+
size_t i = feed_cb_data->index++;
2436+
int ret;
24322437

2433-
hook = find_hook(transaction->ref_store->repo, "reference-transaction");
2434-
if (!hook)
2435-
return ret;
2438+
if (i >= transaction->nr)
2439+
return 1; /* No more refs to process */
24362440

2437-
strvec_pushl(&proc.args, hook, state, NULL);
2438-
proc.in = -1;
2439-
proc.stdout_to_stderr = 1;
2440-
proc.trace2_hook_name = "reference-transaction";
2441+
update = transaction->updates[i];
24412442

2442-
ret = start_command(&proc);
2443-
if (ret)
2444-
return ret;
2443+
if (update->flags & REF_LOG_ONLY)
2444+
return 0;
24452445

2446-
sigchain_push(SIGPIPE, SIG_IGN);
2446+
strbuf_reset(buf);
24472447

2448-
for (size_t i = 0; i < transaction->nr; i++) {
2449-
struct ref_update *update = transaction->updates[i];
2448+
if (!(update->flags & REF_HAVE_OLD))
2449+
strbuf_addf(buf, "%s ", oid_to_hex(null_oid(the_hash_algo)));
2450+
else if (update->old_target)
2451+
strbuf_addf(buf, "ref:%s ", update->old_target);
2452+
else
2453+
strbuf_addf(buf, "%s ", oid_to_hex(&update->old_oid));
24502454

2451-
if (update->flags & REF_LOG_ONLY)
2452-
continue;
2455+
if (!(update->flags & REF_HAVE_NEW))
2456+
strbuf_addf(buf, "%s ", oid_to_hex(null_oid(the_hash_algo)));
2457+
else if (update->new_target)
2458+
strbuf_addf(buf, "ref:%s ", update->new_target);
2459+
else
2460+
strbuf_addf(buf, "%s ", oid_to_hex(&update->new_oid));
24532461

2454-
strbuf_reset(&buf);
2462+
strbuf_addf(buf, "%s\n", update->refname);
24552463

2456-
if (!(update->flags & REF_HAVE_OLD))
2457-
strbuf_addf(&buf, "%s ", oid_to_hex(null_oid(the_hash_algo)));
2458-
else if (update->old_target)
2459-
strbuf_addf(&buf, "ref:%s ", update->old_target);
2460-
else
2461-
strbuf_addf(&buf, "%s ", oid_to_hex(&update->old_oid));
2464+
ret = write_in_full(hook_stdin_fd, buf->buf, buf->len);
2465+
if (ret < 0 && errno != EPIPE)
2466+
return ret;
24622467

2463-
if (!(update->flags & REF_HAVE_NEW))
2464-
strbuf_addf(&buf, "%s ", oid_to_hex(null_oid(the_hash_algo)));
2465-
else if (update->new_target)
2466-
strbuf_addf(&buf, "ref:%s ", update->new_target);
2467-
else
2468-
strbuf_addf(&buf, "%s ", oid_to_hex(&update->new_oid));
2468+
return 0; /* no more input to feed */
2469+
}
2470+
2471+
static int run_transaction_hook(struct ref_transaction *transaction,
2472+
const char *state)
2473+
{
2474+
struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
2475+
struct transaction_feed_cb_data feed_ctx = { 0 };
2476+
int ret = 0;
24692477

2470-
strbuf_addf(&buf, "%s\n", update->refname);
2478+
strvec_push(&opt.args, state);
24712479

2472-
if (write_in_full(proc.in, buf.buf, buf.len) < 0) {
2473-
if (errno != EPIPE) {
2474-
/* Don't leak errno outside this API */
2475-
errno = 0;
2476-
ret = -1;
2477-
}
2478-
break;
2479-
}
2480-
}
2480+
opt.feed_pipe = transaction_hook_feed_stdin;
2481+
opt.feed_pipe_ctx = transaction;
2482+
opt.feed_pipe_cb_data = &feed_ctx;
24812483

2482-
close(proc.in);
2483-
sigchain_pop(SIGPIPE);
2484-
strbuf_release(&buf);
2484+
strbuf_init(&feed_ctx.buf, 0);
2485+
2486+
ret = run_hooks_opt(transaction->ref_store->repo, "reference-transaction", &opt);
24852487

2486-
ret |= finish_command(&proc);
2488+
strbuf_release(&feed_ctx.buf);
24872489
return ret;
24882490
}
24892491

0 commit comments

Comments
 (0)