Skip to content

Commit 9ac9612

Browse files
nasamuffingitster
authored andcommitted
transport: convert pre-push to hook API
Move the pre-push hook from custom run-command invocations to the new hook API which doesn't require a custom child_process structure and signal toggling. 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 d816637 commit 9ac9612

1 file changed

Lines changed: 51 additions & 44 deletions

File tree

transport.c

Lines changed: 51 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,65 +1316,72 @@ static void die_with_unpushed_submodules(struct string_list *needs_pushing)
13161316
die(_("Aborting."));
13171317
}
13181318

1319-
static int run_pre_push_hook(struct transport *transport,
1320-
struct ref *remote_refs)
1321-
{
1322-
int ret = 0, x;
1323-
struct ref *r;
1324-
struct child_process proc = CHILD_PROCESS_INIT;
1319+
struct feed_pre_push_hook_data {
13251320
struct strbuf buf;
1326-
const char *hook_path = find_hook(the_repository, "pre-push");
1321+
const struct ref *refs;
1322+
};
13271323

1328-
if (!hook_path)
1329-
return 0;
1324+
static int pre_push_hook_feed_stdin(int hook_stdin_fd, void *pp_cb UNUSED, void *pp_task_cb)
1325+
{
1326+
struct feed_pre_push_hook_data *data = pp_task_cb;
1327+
const struct ref *r = data->refs;
1328+
int ret = 0;
13301329

1331-
strvec_push(&proc.args, hook_path);
1332-
strvec_push(&proc.args, transport->remote->name);
1333-
strvec_push(&proc.args, transport->url);
1330+
if (!r)
1331+
return 1; /* no more refs */
13341332

1335-
proc.in = -1;
1336-
proc.trace2_hook_name = "pre-push";
1333+
data->refs = r->next;
13371334

1338-
if (start_command(&proc)) {
1339-
finish_command(&proc);
1340-
return -1;
1335+
switch (r->status) {
1336+
case REF_STATUS_REJECT_NONFASTFORWARD:
1337+
case REF_STATUS_REJECT_REMOTE_UPDATED:
1338+
case REF_STATUS_REJECT_STALE:
1339+
case REF_STATUS_UPTODATE:
1340+
return 0; /* skip refs which won't be pushed */
1341+
default:
1342+
break;
13411343
}
13421344

1343-
sigchain_push(SIGPIPE, SIG_IGN);
1345+
if (!r->peer_ref)
1346+
return 0;
13441347

1345-
strbuf_init(&buf, 256);
1348+
strbuf_reset(&data->buf);
1349+
strbuf_addf(&data->buf, "%s %s %s %s\n",
1350+
r->peer_ref->name, oid_to_hex(&r->new_oid),
1351+
r->name, oid_to_hex(&r->old_oid));
13461352

1347-
for (r = remote_refs; r; r = r->next) {
1348-
if (!r->peer_ref) continue;
1349-
if (r->status == REF_STATUS_REJECT_NONFASTFORWARD) continue;
1350-
if (r->status == REF_STATUS_REJECT_STALE) continue;
1351-
if (r->status == REF_STATUS_REJECT_REMOTE_UPDATED) continue;
1352-
if (r->status == REF_STATUS_UPTODATE) continue;
1353+
ret = write_in_full(hook_stdin_fd, data->buf.buf, data->buf.len);
1354+
if (ret < 0 && errno != EPIPE)
1355+
return ret; /* We do not mind if a hook does not read all refs. */
13531356

1354-
strbuf_reset(&buf);
1355-
strbuf_addf( &buf, "%s %s %s %s\n",
1356-
r->peer_ref->name, oid_to_hex(&r->new_oid),
1357-
r->name, oid_to_hex(&r->old_oid));
1357+
return 0;
1358+
}
13581359

1359-
if (write_in_full(proc.in, buf.buf, buf.len) < 0) {
1360-
/* We do not mind if a hook does not read all refs. */
1361-
if (errno != EPIPE)
1362-
ret = -1;
1363-
break;
1364-
}
1365-
}
1360+
static int run_pre_push_hook(struct transport *transport,
1361+
struct ref *remote_refs)
1362+
{
1363+
struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
1364+
struct feed_pre_push_hook_data data;
1365+
int ret = 0;
1366+
1367+
strvec_push(&opt.args, transport->remote->name);
1368+
strvec_push(&opt.args, transport->url);
13661369

1367-
strbuf_release(&buf);
1370+
strbuf_init(&data.buf, 0);
1371+
data.refs = remote_refs;
13681372

1369-
x = close(proc.in);
1370-
if (!ret)
1371-
ret = x;
1373+
opt.feed_pipe = pre_push_hook_feed_stdin;
1374+
opt.feed_pipe_cb_data = &data;
1375+
1376+
/*
1377+
* pre-push hooks expect stdout & stderr to be separate, so don't merge
1378+
* them to keep backwards compatibility with existing hooks.
1379+
*/
1380+
opt.stdout_to_stderr = 0;
13721381

1373-
sigchain_pop(SIGPIPE);
1382+
ret = run_hooks_opt(the_repository, "pre-push", &opt);
13741383

1375-
x = finish_command(&proc);
1376-
if (!ret)
1377-
ret = x;
1384+
strbuf_release(&data.buf);
13781385

13791386
return ret;
13801387
}

0 commit comments

Comments
 (0)