Johannes Schindelin <Johannes.Schindelin@xxxxxx> 于2020年11月5日周四 上午6:15写道: > not ok 34 - proc-receive: bad protocol (hook --die-readline, builtin protocol) > # > # test_must_fail git -C workbench push origin \ > # HEAD:refs/for/main/topic \ > # >out 2>&1 && > # make_user_friendly_and_stable_output <out >actual && > # > # grep "remote: fatal: protocol error: expected \"old new > # ref\", got \"<ZERO-OID> <COMMIT-A> refs/for/main/topic\"" > # actual && > # > # git -C "$upstream" show-ref >out && > # make_user_friendly_and_stable_output <out >actual && > # cat >expect <<-EOF && > # <COMMIT-A> refs/heads/main > # EOF > # test_cmp expect actual > # > -- snap -- > > The output of `actual` reads like this: > > -- snip -- > remote: # pre-receive hook > remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/main/topic > remote: # proc-receive hook > fatal: unable to write flush packet: Broken pipe > send-pack: unexpected disconnect while reading sideband packet > fatal: the remote end hung up unexpectedly > -- snap -- In this test case, the "proc-receive" hook sends an error message and dies earlier. While "receive-pack" on the other side of the pipe should forward the error message of the "proc-receive" hook to the client side, but there is no such error message in output. It seems that the expected error message is overridden by the broken pipe error message. The broken pipe error is because "receive-pack" sends other commands to the "proc-receive" hook, but the hook dies earlier. > Applying Gábor's patch as obtained from > https://lore.kernel.org/git/20190830121005.GI8571@xxxxxxxxxx/ seemed to > help this issue at first, but then turned out not to prevent the same > issue from happening again. I think this is the right way to fix this issue, even though I cannot reproduce this issue in my laptop. 1. In the `run_proc_receive_hook()` function of "receive-pack", should close the input (proc.in) before reading result from "proc-receive": -- snip -- @@ -1196,11 +1197,12 @@ static int run_proc_receive_hook(struct command *commands, packet_flush(proc.in); } + close(proc.in); + /* Read result from proc-receive */ code = read_proc_receive_report(&reader, commands, &errmsg); cleanup: - close(proc.in); close(proc.out); if (use_sideband) finish_async(&muxer); -- snap -- 2. test helper for proc-receive should consume the input stream before die earlier: -- snip -- @@ -79,9 +79,11 @@ static void proc_receive_read_commands(struct packet_reader *reader, *p++ != ' ' || parse_oid_hex(p, &new_oid, &p) || *p++ != ' ' || - die_readline) + die_readline) { + while (packet_reader_read(reader) != PACKET_READ_EOF); die("protocol error: expected 'old new ref', got '%s'", - reader->line); + die_readline? "<call with --die-readline>": reader->line); + } refname = p; FLEX_ALLOC_STR(cmd, ref_name, refname); oidcpy(&cmd->old_oid, &old_oid); @@ -136,7 +138,7 @@ int cmd__proc_receive(int argc, const char **argv) usage_msg_opt("Too many arguments.", proc_receive_usage, options); packet_reader_init(&reader, 0, NULL, 0, PACKET_READ_CHOMP_NEWLINE | - PACKET_READ_DIE_ON_ERR_PACKET); + PACKET_READ_GENTLE_ON_EOF); sigchain_push(SIGPIPE, SIG_IGN); proc_receive_verison(&reader); -- snap -- I will send a standalone patch using git-send-email command line later. -- Jiang Xin