|
15 | 15 | #include "iterator.h" |
16 | 16 | #include "refs.h" |
17 | 17 | #include "refs/refs-internal.h" |
18 | | -#include "run-command.h" |
19 | 18 | #include "hook.h" |
20 | 19 | #include "object-name.h" |
21 | 20 | #include "odb.h" |
|
26 | 25 | #include "strvec.h" |
27 | 26 | #include "repo-settings.h" |
28 | 27 | #include "setup.h" |
29 | | -#include "sigchain.h" |
30 | 28 | #include "date.h" |
31 | 29 | #include "commit.h" |
32 | 30 | #include "wildmatch.h" |
@@ -2422,68 +2420,72 @@ static int ref_update_reject_duplicates(struct string_list *refnames, |
2422 | 2420 | return 0; |
2423 | 2421 | } |
2424 | 2422 |
|
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) |
2427 | 2429 | { |
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; |
2432 | 2437 |
|
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 */ |
2436 | 2440 |
|
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]; |
2441 | 2442 |
|
2442 | | - ret = start_command(&proc); |
2443 | | - if (ret) |
2444 | | - return ret; |
| 2443 | + if (update->flags & REF_LOG_ONLY) |
| 2444 | + return 0; |
2445 | 2445 |
|
2446 | | - sigchain_push(SIGPIPE, SIG_IGN); |
| 2446 | + strbuf_reset(buf); |
2447 | 2447 |
|
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)); |
2450 | 2454 |
|
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)); |
2453 | 2461 |
|
2454 | | - strbuf_reset(&buf); |
| 2462 | + strbuf_addf(buf, "%s\n", update->refname); |
2455 | 2463 |
|
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; |
2462 | 2467 |
|
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; |
2469 | 2477 |
|
2470 | | - strbuf_addf(&buf, "%s\n", update->refname); |
| 2478 | + strvec_push(&opt.args, state); |
2471 | 2479 |
|
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; |
2481 | 2483 |
|
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); |
2485 | 2487 |
|
2486 | | - ret |= finish_command(&proc); |
| 2488 | + strbuf_release(&feed_ctx.buf); |
2487 | 2489 | return ret; |
2488 | 2490 | } |
2489 | 2491 |
|
|
0 commit comments