git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jiang Xin <worldhello.net@gmail.com>
To: Junio C Hamano <gitster@pobox.com>, Git List <git@vger.kernel.org>
Cc: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Subject: [PATCH v13 0/8] New proc-receive hook for centralized workflow
Date: Sat, 18 Apr 2020 12:03:26 -0400	[thread overview]
Message-ID: <20200418160334.15631-1-worldhello.net@gmail.com> (raw)
In-Reply-To: <20200414123257.27449-1-worldhello.net@gmail.com>

From: Jiang Xin <zhiyou.jx@alibaba-inc.com>

Note: This patches series is based on topic branch `jx/atomic-push`,
      for there are overlap changes between these two topics.

## Changes since v12

1. test: Remove t5412, and move HTTP test cases into t5411.

2. test: Split test cases into multiple files as `t/t5411/test-*.sh`.

3. test: Add test cases for porcelain `git-push` output for
   `pro-receive` hook.  See files 't/t5411/test-*--porcelain.sh'.

4. New patch 5/8 to feed proper commands to `post-receive` hook.

5. Use flag `PACKET_READ_GENTLE_ON_EOF` instead of
   `PACKET_READ_DIE_ON_ERR_PACKET` for `packet_reader_init()`
   when reading result from the 'proc-receive' hook.
   So 'receive-pack' won't die with the `proc-receive` hook.

6.  Add two new options (`--die-version` and `--die-readline`) for
   't/helper/test-proc-receive.c', so we can test unexpected crash of
   'proc-receive' hook.

7. Apply the "SQUASH???" commit.

## Range-diff v12...v13

1:  77a731c151 < -:  ---------- transport: not report a non-head push as a branch
-:  ---------- > 1:  312ee17e84 transport: not report a non-head push as a branch
2:  4c4f7cffff = 2:  e86a3c5a4e connect: export parse_feature_value()
3:  b76900cb0f ! 3:  5adc60e9d1 receive-pack: add new proc-receive hook
    @@ Makefile: TEST_BUILTINS_OBJS += test-parse-pathspec-file.o
      TEST_BUILTINS_OBJS += test-read-cache.o
     
      ## builtin/receive-pack.c ##
    -@@
    - #include "remote.h"
    - #include "connect.h"
    - #include "string-list.h"
    -+#include "string.h"
    - #include "sha1-array.h"
    - #include "connected.h"
    - #include "argv-array.h"
     @@ builtin/receive-pack.c: static void write_head_info(void)
      	packet_flush(1);
      }
    @@ builtin/receive-pack.c: static int run_update_hook(struct command *cmd)
     +
     +	for (;;) {
     +		struct object_id old_oid, new_oid;
    -+		char *status;
    ++		const char *status;
     +		char *refname;
     +		char *remains = NULL;
     +
     +		if (packet_reader_read(reader) != PACKET_READ_NORMAL)
     +			break;
    -+		status = (char *)reader->line;
    ++		status = reader->line;
     +		refname = strchr(status, ' ');
     +		if (refname) {
     +			*refname++ = '\0';
    @@ builtin/receive-pack.c: static int run_update_hook(struct command *cmd)
     +			/* Reset "run_proc_receive" field, and continue to run in "receive-pack" */
     +			hint->run_proc_receive = 0;
     +		} else if (!strcmp("alt", status)) {
    -+			char *alt_ref;
    ++			char *alt_ref = NULL;
    ++			char *p1, *p2;
     +
    -+			alt_ref = remains;
    -+			remains = strchr(alt_ref, ' ');
    -+			if (remains)
    -+				*remains++ = '\0';
    ++			if (!remains) {
    ++				strbuf_addf(errmsg, "proc-receive expected 'alt <ref> <alt-ref> ...', got 'alt %s'\n",
    ++					    refname);
    ++				continue;
    ++			}
    ++			p1 = strchr(remains, '=');
    ++			p2 = strchr(remains, ' ');
    ++			if (!p1) {
    ++				/*
    ++				 * "alt <ref> <alt-ref>", or
    ++				 * "alt <ref> <alt-ref> forced-update"
    ++				 */
    ++				alt_ref = remains;
    ++				remains = p2;
    ++				if (remains)
    ++					*remains++ = '\0';
    ++			} else if (!p2) {
    ++				/* "alt <ref> old-oid=<oid>" */
    ++				alt_ref = NULL;
    ++			} else if (p1 > p2) {
    ++				/* "alt <ref> <alt-ref> old-oid=<oid>" */
    ++				alt_ref = remains;
    ++				remains = p2;
    ++				if (remains)
    ++					*remains++ = '\0';
    ++			} else {
    ++				/* "alt <ref> old-oid=<oid1> new-oid=<oid2>" */
    ++				alt_ref = NULL;
    ++			}
     +
     +			if (hint->extended_status)
     +				strbuf_addstr(&extended_status, hint->extended_status);
     +
    -+			strbuf_addf(&extended_status, "%sref=%s",
    -+				    extended_status.len > 0 ? " ": "",
    -+				    alt_ref);
    ++			/*
    ++			 * Already received an "ok <ref>" response, add an
    ++			 * additional "ref=<ref>" field.
    ++			 */
    ++			if (extended_status.len == 0 &&
    ++			    hint->run_proc_receive & RUN_PROC_RECEIVE_RETURNED)
    ++				strbuf_addf(&extended_status, "ref=%s", refname);
    ++
    ++			if (alt_ref)
    ++				strbuf_addf(&extended_status, "%sref=%s",
    ++					    extended_status.len > 0 ? " ": "",
    ++					    alt_ref);
    ++			else if (extended_status.len > 0)
    ++				/*
    ++				 * Start new extended status for refname, if it
    ++				 * is not the first report for this reference.
    ++				 */
    ++				strbuf_addf(&extended_status, " ref=%s", refname);
     +
     +			if (remains) {
     +				const char *val;
    @@ builtin/receive-pack.c: static int run_update_hook(struct command *cmd)
     +	/* Version negotiaton */
     +	packet_reader_init(&reader, proc.out, NULL, 0,
     +			   PACKET_READ_CHOMP_NEWLINE |
    -+			   PACKET_READ_DIE_ON_ERR_PACKET);
    ++			   PACKET_READ_GENTLE_ON_EOF);
     +	if (use_atomic)
     +		strbuf_addstr(&cap, " atomic");
     +	if (use_push_options)
    @@ t/helper/test-proc-receive.c (new)
     +	NULL
     +};
     +
    -+static int version = 1;
    -+static int verbose = 0;
    ++static int die_version = 0;
    ++static int die_readline = 0;
     +static int no_push_options = 0;
     +static int use_atomic = 0;
     +static int use_push_options = 0;
    ++static int verbose = 0;
    ++static int version = 1;
     +static struct string_list returns = STRING_LIST_INIT_NODUP;
     +
     +struct command {
    @@ t/helper/test-proc-receive.c (new)
     +		}
     +	}
     +
    -+	if (server_version != 1)
    ++	if (server_version != 1 || die_version)
     +		die("bad protocol version: %d", server_version);
     +
     +	packet_write_fmt(1, "version=%d%c%s\n",
    @@ t/helper/test-proc-receive.c (new)
     +		if (parse_oid_hex(reader->line, &old_oid, &p) ||
     +		    *p++ != ' ' ||
     +		    parse_oid_hex(p, &new_oid, &p) ||
    -+		    *p++ != ' ')
    ++		    *p++ != ' ' ||
    ++		    die_readline)
     +			die("protocol error: expected 'old new ref', got '%s'",
     +			    reader->line);
     +		refname = p;
    @@ t/helper/test-proc-receive.c (new)
     +	struct option options[] = {
     +		OPT_BOOL(0, "no-push-options", &no_push_options,
     +			 "disable push options"),
    ++		OPT_BOOL(0, "die-version", &die_version,
    ++			 "die during version negotiation"),
    ++		OPT_BOOL(0, "die-readline", &die_readline,
    ++			 "die when readline"),
     +		OPT_STRING_LIST('r', "return", &returns, "old/new/ref/status/msg",
     +				"return of results"),
     +		OPT__VERBOSE(&verbose, "be verbose"),
    @@ t/helper/test-proc-receive.c (new)
     +	}
     +
     +	if (returns.nr)
    -+		for_each_string_list_item(item, &returns) {
    -+			char *p;
    -+
    -+			p = strstr(item->string, "\\0");
    -+			if (p) {
    -+				*p = '\0';
    -+				p += 2;
    -+				packet_write_fmt(1, "%s%c%s\n", item->string, '\0', p);
    -+			} else {
    -+				packet_write_fmt(1, "%s\n", item->string);
    -+			}
    -+		}
    ++		for_each_string_list_item(item, &returns)
    ++			packet_write_fmt(1, "%s\n", item->string);
     +	packet_flush(1);
     +	sigchain_pop(SIGPIPE);
     +
    @@ t/helper/test-tool.h: int cmd__parse_pathspec_file(int argc, const char** argv);
      int cmd__reach(int argc, const char **argv);
      int cmd__read_cache(int argc, const char **argv);
     
    - ## t/t5411/common-functions.sh ##
    -@@ t/t5411/common-functions.sh: create_commits_in () {
    - # Format the output of git-push, git-show-ref and other commands to make a
    - # user-friendly and stable text.  We can easily prepare the expect text
    - # without having to worry about future changes of the commit ID and spaces
    --# of the output.  We also replce single quotes with double quotes, because
    --# it is boring to prepare unquoted single quotes in expect text.
    -+# of the output.  Single quotes are replaced with double quotes, because
    -+# it is boring to prepare unquoted single quotes in expect text.  We also
    -+# remove some locale error messages, which break test if we turn on
    -+# `GIT_TEST_GETTEXT_POISON=true` in order to test unintentional translations
    -+# on plumbing commands.
    - make_user_friendly_and_stable_output_common () {
    - 	sed \
    - 		-e "s/  *\$//" \
    -@@ t/t5411/common-functions.sh: make_user_friendly_and_stable_output_common () {
    - 		-e "s/$TAG/<TAG-v123>/g" \
    - 		-e "s/$ZERO_OID/<ZERO-OID>/g" \
    - 		-e "s/$(echo $A | cut -c1-7)[0-9a-f]*/<OID-A>/g" \
    --		-e "s/$(echo $B | cut -c1-7)[0-9a-f]*/<OID-B>/g"
    -+		-e "s/$(echo $B | cut -c1-7)[0-9a-f]*/<OID-B>/g" \
    -+		-e "/^error: / d"
    - }
    -
    - ## t/t5411/common-test-cases.sh ##
    -@@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
    - 	EOF
    - 	test_cmp expect actual
    - '
    -+
    -+# Refs of upstream : master(A)  tags/v123  refs/review/master/topic(A)  a/b/c(A)
    -+# Refs of workbench: master(A)  tags/v123
    -+test_expect_success "cleanup" '
    -+	(
    -+		cd "$upstream" &&
    -+		git update-ref -d refs/review/master/topic &&
    -+		git update-ref -d refs/tags/v123 &&
    -+		git update-ref -d refs/heads/a/b/c
    -+	)
    -+'
    -+
    + ## t/t5411/test-0011-no-hook-error.sh (new) ##
    +@@
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
     +# git push         :                       next(A)  refs/for/master/topic(A)
    -+test_expect_success "proc-receive: no hook, fail to push special ref" '
    ++test_expect_success "proc-receive: no hook, fail to push special ref ($PROTOCOL)" '
     +	test_must_fail git -C workbench push origin \
     +		HEAD:next \
     +		HEAD:refs/for/master/topic \
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +
     +# Refs of upstream : master(A)             next(A)
     +# Refs of workbench: master(A)  tags/v123
    -+test_expect_success "cleanup" '
    ++test_expect_success "cleanup ($PROTOCOL)" '
     +	git -C "$upstream" update-ref -d refs/heads/next
     +'
     +
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
     +# git push --atomic: (B)                   next(A)  refs/for/master/topic(A)
    -+test_expect_success "proc-receive: no hook, fail all for atomic push" '
    ++test_expect_success "proc-receive: no hook, all failed for atomic push ($PROTOCOL)" '
     +	test_must_fail git -C workbench push --atomic origin \
     +		$B:master \
     +		HEAD:next \
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +	<COMMIT-A> refs/heads/master
     +	EOF
     +	test_cmp expect actual
    ++'
    +
    + ## t/t5411/test-0012-no-hook-error--porcelain.sh (new) ##
    +@@
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       next(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: no hook, fail to push special ref (--porcelain, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push --porcelain origin \
    ++		HEAD:next \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: error: cannot find hook "proc-receive"
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
    ++	To <URL/of/upstream.git>
    ++	*    HEAD:refs/heads/next    [new branch]
    ++	!    HEAD:refs/for/master/topic    [remote rejected] (fail to run proc-receive hook)
    ++	Done
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	<COMMIT-A> refs/heads/next
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++# Refs of upstream : master(A)             next(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++test_expect_success "cleanup ($PROTOCOL)" '
    ++	git -C "$upstream" update-ref -d refs/heads/next
     +'
     +
    -+test_expect_success "setup proc-receive hook (unknown version)" '
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push --atomic: (B)                   next(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: no hook, all failed for atomic push (--porcelain, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push --porcelain --atomic origin \
    ++		$B:master \
    ++		HEAD:next \
    ++		HEAD:refs/for/master/topic >out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: error: cannot find hook "proc-receive"
    ++	To <URL/of/upstream.git>
    ++	!    <COMMIT-B>:refs/heads/master    [remote rejected] (fail to run proc-receive hook)
    ++	!    HEAD:refs/heads/next    [remote rejected] (fail to run proc-receive hook)
    ++	!    HEAD:refs/for/master/topic    [remote rejected] (fail to run proc-receive hook)
    ++	Done
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    +
    + ## t/t5411/test-0013-bad-protocol.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (unknown version, $PROTOCOL)" '
     +	write_script "$upstream/hooks/proc-receive" <<-EOF
     +	printf >&2 "# proc-receive hook\n"
     +	test-tool proc-receive -v --version 2
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
     +# git push         :                       refs/for/master/topic(A)
    -+test_expect_success "proc-receive: bad protocol (unknown version)" '
    ++test_expect_success "proc-receive: bad protocol (unknown version, $PROTOCOL)" '
     +	test_must_fail git -C workbench push origin \
     +		HEAD:refs/for/master/topic \
     +		>out 2>&1 &&
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +
     +	# Check status report for git-push
     +	sed -n \
    -+		-e "/^To / { s/   */ /g; p; }" \
    -+		-e "/^ / { s/   */ /g; p; }" \
    ++		-e "/^To / { p; n; p; }" \
     +		<actual >actual-report &&
     +	cat >expect <<-EOF &&
     +	To <URL/of/upstream.git>
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +	# Check error message from "receive-pack", but ignore unstable fatal error
     +	# message ("remote: fatal: the remote end hung up unexpectedly") which
     +	# is different from the remote HTTP server with different locale settings.
    -+	sed -n -e "/^remote: error:/ { s/   */ /g; p; }" \
    -+		<actual >actual-error &&
    ++	grep "^remote: error:" <actual >actual-error &&
     +	cat >expect <<-EOF &&
     +	remote: error: proc-receive version "2" is not supported
     +	EOF
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +	test_cmp expect actual
     +'
     +
    -+test_expect_success "setup proc-receive hook (no report)" '
    ++test_expect_success "setup proc-receive hook (hook --die-version, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v --die-version
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/master/topic(A)
    ++test_expect_success "proc-receive: bad protocol (hook --die-version, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: fatal: bad protocol version: 1
    ++	remote: error: proc-receive version "0" is not supported
    ++	To <URL/of/upstream.git>
    ++	 ! [remote rejected] HEAD -> refs/for/master/topic (fail to run proc-receive hook)
    ++	EOF
    ++	test_cmp expect actual &&
    ++
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (hook --die-readline, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v --die-readline
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/master/topic(A)
    ++test_expect_success "proc-receive: bad protocol (hook --die-readline, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: fatal: protocol error: expected "old new ref", got "<ZERO-OID> <COMMIT-A> refs/for/master/topic"
    ++	To <URL/of/upstream.git>
    ++	 ! [remote rejected] HEAD -> refs/for/master/topic (proc-receive failed to report status)
    ++	EOF
    ++	test_cmp expect actual &&
    ++
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (no report, $PROTOCOL)" '
     +	write_script "$upstream/hooks/proc-receive" <<-EOF
     +	printf >&2 "# proc-receive hook\n"
     +	test-tool proc-receive -v
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
     +# git push         :                       next(A)  refs/for/master/topic(A)
    -+test_expect_success "proc-receive: bad protocol (no report)" '
    ++test_expect_success "proc-receive: bad protocol (no report, $PROTOCOL)" '
     +	test_must_fail git -C workbench push origin \
     +		HEAD:refs/heads/next \
     +		HEAD:refs/for/master/topic >out 2>&1 &&
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +
     +# Refs of upstream : master(A)             next(A)
     +# Refs of workbench: master(A)  tags/v123
    -+test_expect_success "cleanup" '
    ++test_expect_success "cleanup ($PROTOCOL)" '
     +	git -C "$upstream" update-ref -d refs/heads/next
     +
     +'
     +
    -+test_expect_success "setup proc-receive hook (no ref)" '
    ++test_expect_success "setup proc-receive hook (no ref, $PROTOCOL)" '
     +	write_script "$upstream/hooks/proc-receive" <<-EOF
     +	printf >&2 "# proc-receive hook\n"
     +	test-tool proc-receive -v \
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
     +# git push         :                       refs/for/master/topic
    -+test_expect_success "proc-receive: bad protocol (no ref)" '
    ++test_expect_success "proc-receive: bad protocol (no ref, $PROTOCOL)" '
     +	test_must_fail git -C workbench push origin \
     +		HEAD:refs/for/master/topic\
     +		>out 2>&1 &&
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +	test_cmp expect actual
     +'
     +
    -+test_expect_success "setup proc-receive hook (unknown status)" '
    ++test_expect_success "setup proc-receive hook (unknown status, $PROTOCOL)" '
     +	write_script "$upstream/hooks/proc-receive" <<-EOF
     +	printf >&2 "# proc-receive hook\n"
     +	test-tool proc-receive -v \
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
     +# git push         :                       refs/for/master/topic
    -+test_expect_success "proc-receive: bad protocol (unknown status)" '
    ++test_expect_success "proc-receive: bad protocol (unknown status, $PROTOCOL)" '
     +	test_must_fail git -C workbench push origin \
     +			HEAD:refs/for/master/topic \
     +			>out 2>&1 &&
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +	EOF
     +	test_cmp expect actual
     +'
    -+
    -+test_expect_success "setup proc-receive hook (ng)" '
    +
    + ## t/t5411/test-0014-bad-protocol--porcelain.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (unknown version, $PROTOCOL)" '
     +	write_script "$upstream/hooks/proc-receive" <<-EOF
     +	printf >&2 "# proc-receive hook\n"
    -+	test-tool proc-receive -v \
    -+		-r "ng refs/for/master/topic"
    ++	test-tool proc-receive -v --version 2
     +	EOF
     +'
     +
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
    -+# git push         :                       refs/for/master/topic
    -+test_expect_success "proc-receive: fail to update (ng)" '
    -+	test_must_fail git -C workbench push origin \
    ++# git push         :                       refs/for/master/topic(A)
    ++test_expect_success "proc-receive: bad protocol (unknown version, --porcelain, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push --porcelain origin \
     +		HEAD:refs/for/master/topic \
     +		>out 2>&1 &&
     +	make_user_friendly_and_stable_output <out >actual &&
    ++
    ++	# Check status report for git-push
    ++	sed -n \
    ++		-e "/^To / { p; n; p; n; p; }" \
    ++		<actual >actual-report &&
     +	cat >expect <<-EOF &&
    -+	remote: # pre-receive hook
    -+	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    -+	remote: # proc-receive hook
    -+	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    -+	remote: proc-receive> ng refs/for/master/topic
     +	To <URL/of/upstream.git>
    -+	 ! [remote rejected] HEAD -> refs/for/master/topic (failed)
    ++	!    HEAD:refs/for/master/topic    [remote rejected] (fail to run proc-receive hook)
    ++	Done
     +	EOF
    -+	test_cmp expect actual &&
    ++	test_cmp expect actual-report &&
    ++
    ++	# Check error message from "receive-pack", but ignore unstable fatal error
    ++	# message ("remote: fatal: the remote end hung up unexpectedly") which
    ++	# is different from the remote HTTP server with different locale settings.
    ++	grep "^remote: error:" <actual >actual-error &&
    ++	cat >expect <<-EOF &&
    ++	remote: error: proc-receive version "2" is not supported
    ++	EOF
    ++	test_cmp expect actual-error &&
    ++
     +	git -C "$upstream" show-ref >out &&
     +	make_user_friendly_and_stable_output <out >actual &&
     +	cat >expect <<-EOF &&
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +	test_cmp expect actual
     +'
     +
    -+test_expect_success "setup proc-receive hook (ng message)" '
    ++test_expect_success "setup proc-receive hook (no report, $PROTOCOL)" '
     +	write_script "$upstream/hooks/proc-receive" <<-EOF
     +	printf >&2 "# proc-receive hook\n"
    -+	test-tool proc-receive -v \
    -+		-r "ng refs/for/master/topic error msg"
    ++	test-tool proc-receive -v
     +	EOF
     +'
     +
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
    -+# git push         :                       refs/for/master/topic
    -+test_expect_success "proc-receive: fail to update (ng message)" '
    -+	test_must_fail git -C workbench push origin \
    -+		HEAD:refs/for/master/topic \
    -+		>out 2>&1 &&
    ++# git push         :                       next(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: bad protocol (no report, --porcelain, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push --porcelain origin \
    ++		HEAD:refs/heads/next \
    ++		HEAD:refs/for/master/topic >out 2>&1 &&
     +	make_user_friendly_and_stable_output <out >actual &&
     +	cat >expect <<-EOF &&
     +	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
     +	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
     +	remote: # proc-receive hook
     +	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    -+	remote: proc-receive> ng refs/for/master/topic error msg
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
     +	To <URL/of/upstream.git>
    -+	 ! [remote rejected] HEAD -> refs/for/master/topic (error msg)
    ++	*    HEAD:refs/heads/next    [new branch]
    ++	!    HEAD:refs/for/master/topic    [remote rejected] (proc-receive failed to report status)
    ++	Done
     +	EOF
     +	test_cmp expect actual &&
     +	git -C "$upstream" show-ref >out &&
     +	make_user_friendly_and_stable_output <out >actual &&
     +	cat >expect <<-EOF &&
     +	<COMMIT-A> refs/heads/master
    ++	<COMMIT-A> refs/heads/next
     +	EOF
     +	test_cmp expect actual
     +'
     +
    -+test_expect_success "setup proc-receive hook (unexpected ref)" '
    ++# Refs of upstream : master(A)             next(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++test_expect_success "cleanup ($PROTOCOL)" '
    ++	git -C "$upstream" update-ref -d refs/heads/next
    ++
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (no ref, $PROTOCOL)" '
     +	write_script "$upstream/hooks/proc-receive" <<-EOF
     +	printf >&2 "# proc-receive hook\n"
     +	test-tool proc-receive -v \
    -+		-r "ok refs/heads/master"
    ++		-r "ok"
     +	EOF
     +'
     +
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
    -+# git push         : (B)                   refs/for/master/topic
    -+test_expect_success "proc-receive: report on unexpected ref" '
    -+	test_must_fail git -C workbench push origin \
    -+		$B:refs/heads/master \
    -+		HEAD:refs/for/master/topic \
    ++# git push         :                       refs/for/master/topic
    ++test_expect_success "proc-receive: bad protocol (no ref, --porcelain, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push --porcelain origin \
    ++		HEAD:refs/for/master/topic\
     +		>out 2>&1 &&
     +	make_user_friendly_and_stable_output <out >actual &&
     +	cat >expect <<-EOF &&
     +	remote: # pre-receive hook
    -+	remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
     +	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
     +	remote: # proc-receive hook
     +	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    -+	remote: proc-receive> ok refs/heads/master
    -+	remote: error: proc-receive reported status on unexpected ref: refs/heads/master
    -+	remote: # post-receive hook
    -+	remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
    ++	remote: proc-receive> ok
    ++	remote: error: proc-receive expected "<status> <ref> ...", got "ok"
     +	To <URL/of/upstream.git>
    -+	 <OID-A>..<OID-B> <COMMIT-B> -> master
    -+	 ! [remote rejected] HEAD -> refs/for/master/topic (proc-receive failed to report status)
    ++	!    HEAD:refs/for/master/topic    [remote rejected] (proc-receive failed to report status)
    ++	Done
     +	EOF
     +	test_cmp expect actual &&
     +	git -C "$upstream" show-ref >out &&
     +	make_user_friendly_and_stable_output <out >actual &&
     +	cat >expect <<-EOF &&
    -+	<COMMIT-B> refs/heads/master
    ++	<COMMIT-A> refs/heads/master
     +	EOF
     +	test_cmp expect actual
     +'
     +
    -+# Refs of upstream : master(B)
    -+# Refs of workbench: master(A)  tags/v123
    -+test_expect_success "cleanup" '
    -+	git -C "$upstream" update-ref refs/heads/master $A
    -+'
    -+
    -+test_expect_success "setup proc-receive hook (ok)" '
    ++test_expect_success "setup proc-receive hook (unknown status, $PROTOCOL)" '
     +	write_script "$upstream/hooks/proc-receive" <<-EOF
     +	printf >&2 "# proc-receive hook\n"
     +	test-tool proc-receive -v \
    -+		-r "ok refs/for/master/topic"
    ++		-r "xx refs/for/master/topic"
     +	EOF
     +'
     +
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
     +# git push         :                       refs/for/master/topic
    -+test_expect_success "proc-receive: ok" '
    -+	git -C workbench push origin \
    -+		HEAD:refs/for/master/topic \
    -+		>out 2>&1 &&
    ++test_expect_success "proc-receive: bad protocol (unknown status, --porcelain, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push --porcelain origin \
    ++			HEAD:refs/for/master/topic \
    ++			>out 2>&1 &&
     +	make_user_friendly_and_stable_output <out >actual &&
     +	cat >expect <<-EOF &&
     +	remote: # pre-receive hook
     +	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
     +	remote: # proc-receive hook
     +	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    -+	remote: proc-receive> ok refs/for/master/topic
    -+	remote: # post-receive hook
    -+	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> xx refs/for/master/topic
    ++	remote: error: proc-receive reported bad status "xx" on ref "refs/for/master/topic"
     +	To <URL/of/upstream.git>
    -+	 * [new reference] HEAD -> refs/for/master/topic
    ++	!    HEAD:refs/for/master/topic    [remote rejected] (proc-receive failed to report status)
    ++	Done
     +	EOF
     +	test_cmp expect actual &&
     +	git -C "$upstream" show-ref >out &&
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +	<COMMIT-A> refs/heads/master
     +	EOF
     +	test_cmp expect actual
    ++'
    +
    + ## t/t5411/test-0020-report-ng.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (ng, no message, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ng refs/for/master/topic"
    ++	EOF
     +'
     +
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
    -+# git push         :                       refs/for/a/b/c/my/topic
    -+test_expect_success "proc-receive: failed to report status" '
    ++# git push         :                       refs/for/master/topic
    ++test_expect_success "proc-receive: fail to update (ng, no message, $PROTOCOL)" '
     +	test_must_fail git -C workbench push origin \
    -+		HEAD:refs/for/a/b/c/my/topic \
    ++		HEAD:refs/for/master/topic \
     +		>out 2>&1 &&
     +	make_user_friendly_and_stable_output <out >actual &&
     +	cat >expect <<-EOF &&
     +	remote: # pre-receive hook
    -+	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/my/topic
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
     +	remote: # proc-receive hook
    -+	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/my/topic
    -+	remote: proc-receive> ok refs/for/master/topic
    -+	remote: error: proc-receive reported status on unknown ref: refs/for/master/topic
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> ng refs/for/master/topic
     +	To <URL/of/upstream.git>
    -+	 ! [remote rejected] HEAD -> refs/for/a/b/c/my/topic (proc-receive failed to report status)
    ++	 ! [remote rejected] HEAD -> refs/for/master/topic (failed)
     +	EOF
     +	test_cmp expect actual &&
     +	git -C "$upstream" show-ref >out &&
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +	test_cmp expect actual
     +'
     +
    -+# Refs of upstream : master(A)
    -+# Refs of workbench: master(A)  tags/v123
    -+# git push -o ...  :                       refs/for/master/topic
    -+test_expect_success "proc-receive: not support push options" '
    -+	test_must_fail git -C workbench push \
    ++test_expect_success "setup proc-receive hook (ng message, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ng refs/for/master/topic error msg"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/master/topic
    ++test_expect_success "proc-receive: fail to update (ng, with message, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> ng refs/for/master/topic error msg
    ++	To <URL/of/upstream.git>
    ++	 ! [remote rejected] HEAD -> refs/for/master/topic (error msg)
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    +
    + ## t/t5411/test-0021-report-ng--porcelain.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (ng, no message, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ng refs/for/master/topic"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/master/topic
    ++test_expect_success "proc-receive: fail to update (ng, no message, --porcelain, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push --porcelain origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> ng refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	!    HEAD:refs/for/master/topic    [remote rejected] (failed)
    ++	Done
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (ng message, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ng refs/for/master/topic error msg"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/master/topic
    ++test_expect_success "proc-receive: fail to update (ng, with message, --porcelain, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push --porcelain origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> ng refs/for/master/topic error msg
    ++	To <URL/of/upstream.git>
    ++	!    HEAD:refs/for/master/topic    [remote rejected] (error msg)
    ++	Done
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    +
    + ## t/t5411/test-0022-report-unexpect-ref.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ok refs/heads/master"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         : (B)                   refs/for/master/topic
    ++test_expect_success "proc-receive: report unexpected ref ($PROTOCOL)" '
    ++	test_must_fail git -C workbench push origin \
    ++		$B:refs/heads/master \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> ok refs/heads/master
    ++	remote: error: proc-receive reported status on unexpected ref: refs/heads/master
    ++	remote: # post-receive hook
    ++	remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
    ++	To <URL/of/upstream.git>
    ++	 <OID-A>..<OID-B> <COMMIT-B> -> master
    ++	 ! [remote rejected] HEAD -> refs/for/master/topic (proc-receive failed to report status)
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-B> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++# Refs of upstream : master(B)
    ++# Refs of workbench: master(A)  tags/v123
    ++test_expect_success "cleanup ($PROTOCOL)" '
    ++	git -C "$upstream" update-ref refs/heads/master $A
    ++'
    +
    + ## t/t5411/test-0023-report-unexpect-ref--porcelain.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ok refs/heads/master"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         : (B)                   refs/for/master/topic
    ++test_expect_success "proc-receive: report unexpected ref (--porcelain, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push --porcelain origin \
    ++		$B:refs/heads/master \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> ok refs/heads/master
    ++	remote: error: proc-receive reported status on unexpected ref: refs/heads/master
    ++	remote: # post-receive hook
    ++	remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
    ++	To <URL/of/upstream.git>
    ++	     <COMMIT-B>:refs/heads/master    <OID-A>..<OID-B>
    ++	!    HEAD:refs/for/master/topic    [remote rejected] (proc-receive failed to report status)
    ++	Done
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-B> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++# Refs of upstream : master(B)
    ++# Refs of workbench: master(A)  tags/v123
    ++test_expect_success "cleanup ($PROTOCOL)" '
    ++	git -C "$upstream" update-ref refs/heads/master $A
    ++'
    +
    + ## t/t5411/test-0024-report-unknown-ref.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ok refs/for/master/topic"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/a/b/c/my/topic
    ++test_expect_success "proc-receive: report unknown reference ($PROTOCOL)" '
    ++	test_must_fail git -C workbench push origin \
    ++		HEAD:refs/for/a/b/c/my/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/my/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/my/topic
    ++	remote: proc-receive> ok refs/for/master/topic
    ++	remote: error: proc-receive reported status on unknown ref: refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	 ! [remote rejected] HEAD -> refs/for/a/b/c/my/topic (proc-receive failed to report status)
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    +
    + ## t/t5411/test-0025-report-unknown-ref--porcelain.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ok refs/for/master/topic"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/a/b/c/my/topic
    ++test_expect_success "proc-receive: report unknown reference (--porcelain, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push --porcelain origin \
    ++		HEAD:refs/for/a/b/c/my/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/my/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/my/topic
    ++	remote: proc-receive> ok refs/for/master/topic
    ++	remote: error: proc-receive reported status on unknown ref: refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	!    HEAD:refs/for/a/b/c/my/topic    [remote rejected] (proc-receive failed to report status)
    ++	Done
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    +
    + ## t/t5411/test-0026-push-options.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook and disable push-options ($PROTOCOL)" '
    ++	git -C "$upstream" config receive.advertisePushOptions false &&
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ok refs/for/master/topic"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push -o ...  :                       refs/for/master/topic
    ++test_expect_success "proc-receive: not support push options ($PROTOCOL)" '
    ++	test_must_fail git -C workbench push \
     +		-o issue=123 \
     +		-o reviewer=user1 \
     +		origin \
     +		HEAD:refs/for/master/topic \
     +		>out 2>&1 &&
     +	make_user_friendly_and_stable_output <out >actual &&
    -+	test_i18ngrep "fatal: the receiving end does not support push options" \
    -+		actual &&
    ++	test_i18ngrep "fatal: the receiving end does not support push options" \
    ++		actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "enable push options ($PROTOCOL)" '
    ++	git -C "$upstream" config receive.advertisePushOptions true
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push -o ...  :                       next(A)  refs/for/master/topic
    ++test_expect_success "proc-receive: push with options ($PROTOCOL)" '
    ++	git -C workbench push \
    ++		--atomic \
    ++		-o issue=123 \
    ++		-o reviewer=user1 \
    ++		origin \
    ++		HEAD:refs/heads/next \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive: atomic push_options
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive< issue=123
    ++	remote: proc-receive< reviewer=user1
    ++	remote: proc-receive> ok refs/for/master/topic
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	 * [new branch] HEAD -> next
    ++	 * [new reference] HEAD -> refs/for/master/topic
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	<COMMIT-A> refs/heads/next
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++# Refs of upstream : master(A)             next(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++test_expect_success "cleanup ($PROTOCOL)" '
    ++	git -C "$upstream" update-ref -d refs/heads/next
    ++'
    +
    + ## t/t5411/test-0027-push-options--porcelain.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook and disable push-options ($PROTOCOL)" '
    ++	git -C "$upstream" config receive.advertisePushOptions false &&
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ok refs/for/master/topic"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push -o ...  :                       refs/for/master/topic
    ++test_expect_success "proc-receive: not support push options (--porcelain, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push \
    ++		--porcelain \
    ++		-o issue=123 \
    ++		-o reviewer=user1 \
    ++		origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	test_i18ngrep "fatal: the receiving end does not support push options" \
    ++		actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "enable push options ($PROTOCOL)" '
    ++	git -C "$upstream" config receive.advertisePushOptions true
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push -o ...  :                       next(A)  refs/for/master/topic
    ++test_expect_success "proc-receive: push with options (--porcelain, $PROTOCOL)" '
    ++	git -C workbench push \
    ++		--porcelain \
    ++		--atomic \
    ++		-o issue=123 \
    ++		-o reviewer=user1 \
    ++		origin \
    ++		HEAD:refs/heads/next \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive: atomic push_options
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive< issue=123
    ++	remote: proc-receive< reviewer=user1
    ++	remote: proc-receive> ok refs/for/master/topic
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	*    HEAD:refs/heads/next    [new branch]
    ++	*    HEAD:refs/for/master/topic    [new reference]
    ++	Done
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	<COMMIT-A> refs/heads/next
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++# Refs of upstream : master(A)             next(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++test_expect_success "cleanup ($PROTOCOL)" '
    ++	git -C "$upstream" update-ref -d refs/heads/next
    ++'
    +
    + ## t/t5411/test-0030-report-ok.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (ok, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ok refs/for/master/topic"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/master/topic
    ++test_expect_success "proc-receive: ok ($PROTOCOL)" '
    ++	git -C workbench push origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> ok refs/for/master/topic
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	 * [new reference] HEAD -> refs/for/master/topic
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    +
    + ## t/t5411/test-0031-report-ok--porcelain.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (ok, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ok refs/for/master/topic"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/master/topic
    ++test_expect_success "proc-receive: ok (--porcelain, $PROTOCOL)" '
    ++	git -C workbench push --porcelain origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> ok refs/for/master/topic
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	*    HEAD:refs/for/master/topic    [new reference]
    ++	Done
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    +
    + ## t/t5411/test-0032-report-alt.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (alt <ref>, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report alt (alt <ref>, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic
    ++	remote: error: proc-receive expected "alt <ref> <alt-ref> ...", got "alt refs/for/master/topic"
    ++	To <URL/of/upstream.git>
    ++	 ! [remote rejected] HEAD -> refs/for/master/topic (proc-receive failed to report status)
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (alt <ref> <alt-ref>, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic refs/pull/123/head"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report alt (alt <ref> <alt-ref>, $PROTOCOL)" '
    ++	git -C workbench push origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic refs/pull/123/head
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	 * [new reference] HEAD -> refs/for/master/topic
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (alt <ref> <alt-ref> forced-update, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic refs/pull/123/head forced-update"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report alt (alt <ref> <alt-ref> forced-update, $PROTOCOL)" '
    ++	git -C workbench push origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic refs/pull/123/head forced-update
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	 * [new reference] HEAD -> refs/for/master/topic
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (alt <ref> <alt-ref> old-oid=X, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic refs/pull/123/head old-oid=$B"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report alt (alt <ref> <alt-ref> old-oid=X, $PROTOCOL)" '
    ++	git -C workbench push origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic refs/pull/123/head old-oid=<COMMIT-B>
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	 * [new reference] HEAD -> refs/for/master/topic
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (alt <ref> old-oid=X, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic old-oid=$B"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report alt (alt <ref> old-oid=X, $PROTOCOL)" '
    ++	git -C workbench push origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic old-oid=<COMMIT-B>
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	 * [new reference] HEAD -> refs/for/master/topic
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (alt <ref> old-oid=X new-oid=Y, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic old-oid=$A new-oid=$B"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report alt (alt <ref> old-oid=X new-oid=Y, $PROTOCOL)" '
    ++	git -C workbench push origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic old-oid=<COMMIT-A> new-oid=<COMMIT-B>
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	 * [new reference] HEAD -> refs/for/master/topic
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (with multiple alt reports, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ok refs/for/a/b/c/topic" \
    ++		-r "alt refs/for/next/topic refs/pull/123/head" \
    ++		-r "alt refs/for/master/topic refs/pull/124/head old-oid=$B forced-update new-oid=$A"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: with multiple alt reports ($PROTOCOL)" '
    ++	git -C workbench push origin \
    ++		HEAD:refs/for/next/topic \
    ++		HEAD:refs/for/a/b/c/topic \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> ok refs/for/a/b/c/topic
    ++	remote: proc-receive> alt refs/for/next/topic refs/pull/123/head
    ++	remote: proc-receive> alt refs/for/master/topic refs/pull/124/head old-oid=<COMMIT-B> forced-update new-oid=<COMMIT-A>
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	 * [new reference] HEAD -> refs/for/next/topic
    ++	 * [new reference] HEAD -> refs/for/a/b/c/topic
    ++	 * [new reference] HEAD -> refs/for/master/topic
    ++	EOF
    ++	test_cmp expect actual &&
    ++
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    +
    + ## t/t5411/test-0033-report-alt--porcelain.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (alt <ref>, --porcelain, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report alt (alt <ref>, --porcelain, $PROTOCOL)" '
    ++	test_must_fail git -C workbench push --porcelain origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic
    ++	remote: error: proc-receive expected "alt <ref> <alt-ref> ...", got "alt refs/for/master/topic"
    ++	To <URL/of/upstream.git>
    ++	!    HEAD:refs/for/master/topic    [remote rejected] (proc-receive failed to report status)
    ++	Done
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (alt <ref> <alt-ref>, --porcelain, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic refs/pull/123/head"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report alt (alt <ref> <alt-ref>, --porcelain, $PROTOCOL)" '
    ++	git -C workbench push --porcelain origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic refs/pull/123/head
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	*    HEAD:refs/for/master/topic    [new reference]
    ++	Done
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (alt <ref> <alt-ref> forced-update, --porcelain, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic refs/pull/123/head forced-update"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report alt (alt <ref> <alt-ref> forced-update, --porcelain, $PROTOCOL)" '
    ++	git -C workbench push --porcelain origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic refs/pull/123/head forced-update
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	*    HEAD:refs/for/master/topic    [new reference]
    ++	Done
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (alt <ref> <alt-ref> old-oid=X, --porcelain, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic refs/pull/123/head old-oid=$B"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report alt (alt <ref> <alt-ref> old-oid=X, --porcelain, $PROTOCOL)" '
    ++	git -C workbench push --porcelain origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic refs/pull/123/head old-oid=<COMMIT-B>
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	*    HEAD:refs/for/master/topic    [new reference]
    ++	Done
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (alt <ref> old-oid=X, --porcelain, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic old-oid=$B"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report alt (alt <ref> old-oid=X, --porcelain, $PROTOCOL)" '
    ++	git -C workbench push --porcelain origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic old-oid=<COMMIT-B>
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	*    HEAD:refs/for/master/topic    [new reference]
    ++	Done
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (alt <ref> old-oid=X new-oid=Y, --porcelain, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic old-oid=$A new-oid=$B"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report alt (alt <ref> old-oid=X new-oid=Y, --porcelain, $PROTOCOL)" '
    ++	git -C workbench push --porcelain origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic old-oid=<COMMIT-A> new-oid=<COMMIT-B>
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	*    HEAD:refs/for/master/topic    [new reference]
    ++	Done
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (with multiple alt reports, --porcelain, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ok refs/for/a/b/c/topic" \
    ++		-r "alt refs/for/next/topic refs/pull/123/head" \
    ++		-r "alt refs/for/master/topic refs/pull/124/head old-oid=$B forced-update new-oid=$A"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: with multiple alt reports (--porcelain, $PROTOCOL)" '
    ++	git -C workbench push --porcelain origin \
    ++		HEAD:refs/for/next/topic \
    ++		HEAD:refs/for/a/b/c/topic \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> ok refs/for/a/b/c/topic
    ++	remote: proc-receive> alt refs/for/next/topic refs/pull/123/head
    ++	remote: proc-receive> alt refs/for/master/topic refs/pull/124/head old-oid=<COMMIT-B> forced-update new-oid=<COMMIT-A>
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	*    HEAD:refs/for/next/topic    [new reference]
    ++	*    HEAD:refs/for/a/b/c/topic    [new reference]
    ++	*    HEAD:refs/for/master/topic    [new reference]
    ++	Done
    ++	EOF
    ++	test_cmp expect actual &&
    ++
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    +
    + ## t/t5411/test-0034-report-ft.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (ft, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ft refs/for/master/topic"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/master/topic(B)
    ++test_expect_success "proc-receive: fall throught, let receive-pack to execute ($PROTOCOL)" '
    ++	git -C workbench push origin \
    ++		$B:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
    ++	remote: proc-receive> ft refs/for/master/topic
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	 * [new reference] <COMMIT-B> -> refs/for/master/topic
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-B> refs/for/master/topic
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++# Refs of upstream : master(A)             refs/for/master/topic(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++test_expect_success "cleanup ($PROTOCOL)" '
    ++	git -C "$upstream" update-ref -d refs/for/master/topic
    ++'
    +
    + ## t/t5411/test-0035-report-ft--porcelain.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (ft, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ft refs/for/master/topic"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/master/topic(B)
    ++test_expect_success "proc-receive: fall throught, let receive-pack to execute (--porcelain, $PROTOCOL)" '
    ++	git -C workbench push --porcelain origin \
    ++		$B:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
    ++	remote: proc-receive> ft refs/for/master/topic
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	*    <COMMIT-B>:refs/for/master/topic    [new reference]
    ++	Done
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-B> refs/for/master/topic
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++# Refs of upstream : master(A)             refs/for/master/topic(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++test_expect_success "cleanup ($PROTOCOL)" '
    ++	git -C "$upstream" update-ref -d refs/for/master/topic
    ++'
    +
    + ## t/t5411/test-0036-report-multi-alt-for-one-ref.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (multiple alt, no alt-ref for the 1st resp, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic old-oid=$A new-oid=$B" \
    ++		-r "alt refs/for/master/topic refs/changes/24/124/1 old-oid=$ZERO_OID new-oid=$A" \
    ++		-r "alt refs/for/master/topic refs/changes/25/125/1 old-oid=$A new-oid=$B"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report multiple alt, no alt-ref for the 1st resp ($PROTOCOL)" '
    ++	git -C workbench push origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic old-oid=<COMMIT-A> new-oid=<COMMIT-B>
    ++	remote: proc-receive> alt refs/for/master/topic refs/changes/24/124/1 old-oid=<ZERO-OID> new-oid=<COMMIT-A>
    ++	remote: proc-receive> alt refs/for/master/topic refs/changes/25/125/1 old-oid=<COMMIT-A> new-oid=<COMMIT-B>
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	 * [new reference] HEAD -> refs/for/master/topic
    ++	EOF
    ++	test_cmp expect actual &&
     +	git -C "$upstream" show-ref >out &&
     +	make_user_friendly_and_stable_output <out >actual &&
     +	cat >expect <<-EOF &&
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +	test_cmp expect actual
     +'
     +
    -+test_expect_success "enable push options" '
    -+	git -C "$upstream" config receive.advertisePushOptions true
    ++test_expect_success "setup proc-receive hook (multiple alt, no alt-ref for the 2nd resp, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic refs/changes/24/124/1 old-oid=$ZERO_OID new-oid=$A" \
    ++		-r "alt refs/for/master/topic old-oid=$A new-oid=$B" \
    ++		-r "alt refs/for/master/topic refs/changes/25/125/1 old-oid=$B new-oid=$A forced-update"
    ++	EOF
     +'
     +
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
    -+# git push -o ...  :                       next(A)  refs/for/master/topic
    -+test_expect_success "proc-receive: push with options" '
    -+	git -C workbench push \
    -+		--atomic \
    -+		-o issue=123 \
    -+		-o reviewer=user1 \
    -+		origin \
    -+		HEAD:refs/heads/next \
    ++# git push         :                       refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report multiple alt, no alt-ref for the 2nd resp ($PROTOCOL)" '
    ++	git -C workbench push origin \
     +		HEAD:refs/for/master/topic \
     +		>out 2>&1 &&
     +	make_user_friendly_and_stable_output <out >actual &&
     +	cat >expect <<-EOF &&
     +	remote: # pre-receive hook
    -+	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
     +	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
     +	remote: # proc-receive hook
    -+	remote: proc-receive: atomic push_options
     +	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    -+	remote: proc-receive< issue=123
    -+	remote: proc-receive< reviewer=user1
    -+	remote: proc-receive> ok refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic refs/changes/24/124/1 old-oid=<ZERO-OID> new-oid=<COMMIT-A>
    ++	remote: proc-receive> alt refs/for/master/topic old-oid=<COMMIT-A> new-oid=<COMMIT-B>
    ++	remote: proc-receive> alt refs/for/master/topic refs/changes/25/125/1 old-oid=<COMMIT-B> new-oid=<COMMIT-A> forced-update
     +	remote: # post-receive hook
    -+	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
     +	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
     +	To <URL/of/upstream.git>
    -+	 * [new branch] HEAD -> next
     +	 * [new reference] HEAD -> refs/for/master/topic
     +	EOF
     +	test_cmp expect actual &&
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +	make_user_friendly_and_stable_output <out >actual &&
     +	cat >expect <<-EOF &&
     +	<COMMIT-A> refs/heads/master
    -+	<COMMIT-A> refs/heads/next
     +	EOF
     +	test_cmp expect actual
     +'
     +
    -+# Refs of upstream : master(A)             next(A)
    ++test_expect_success "setup proc-receive hook (ok and alt for the same ref, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ok refs/for/master/topic" \
    ++		-r "alt refs/for/master/topic refs/changes/24/124/1 new-oid=$B old-oid=$A"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
    -+test_expect_success "cleanup" '
    -+	git -C "$upstream" update-ref -d refs/heads/next
    ++# git push         :                       refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report ok and alt for the same ref ($PROTOCOL)" '
    ++	git -C workbench push origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> ok refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic refs/changes/24/124/1 new-oid=<COMMIT-B> old-oid=<COMMIT-A>
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	 * [new reference] HEAD -> refs/for/master/topic
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
     +'
     +
    -+test_expect_success "setup proc-receive hook (ft)" '
    ++test_expect_success "setup proc-receive hook (multiple responses, $PROTOCOL)" '
     +	write_script "$upstream/hooks/proc-receive" <<-EOF
     +	printf >&2 "# proc-receive hook\n"
     +	test-tool proc-receive -v \
    -+		-r "ft refs/for/master/topic"
    ++		-r "alt refs/for/master/topic refs/changes/23/123/1" \
    ++		-r "alt refs/for/master/topic refs/changes/24/124/2 old-oid=$A new-oid=$B"
     +	EOF
     +'
     +
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
    -+# git push         :                       refs/for/master/topic(B)
    -+test_expect_success "proc-receive: fall throught, let receive-pack to execute" '
    ++# git push         :                       refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report multiple response ($PROTOCOL)" '
     +	git -C workbench push origin \
    -+		$B:refs/for/master/topic \
    ++		HEAD:refs/for/master/topic \
     +		>out 2>&1 &&
     +	make_user_friendly_and_stable_output <out >actual &&
     +	cat >expect <<-EOF &&
     +	remote: # pre-receive hook
    -+	remote: pre-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
     +	remote: # proc-receive hook
    -+	remote: proc-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
    -+	remote: proc-receive> ft refs/for/master/topic
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic refs/changes/23/123/1
    ++	remote: proc-receive> alt refs/for/master/topic refs/changes/24/124/2 old-oid=<COMMIT-A> new-oid=<COMMIT-B>
     +	remote: # post-receive hook
    -+	remote: post-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
     +	To <URL/of/upstream.git>
    -+	 * [new reference] <COMMIT-B> -> refs/for/master/topic
    ++	 * [new reference] HEAD -> refs/for/master/topic
     +	EOF
     +	test_cmp expect actual &&
     +	git -C "$upstream" show-ref >out &&
     +	make_user_friendly_and_stable_output <out >actual &&
     +	cat >expect <<-EOF &&
    -+	<COMMIT-B> refs/for/master/topic
     +	<COMMIT-A> refs/heads/master
     +	EOF
     +	test_cmp expect actual
    ++'
    +
    + ## t/t5411/test-0037-report-multi-alt-for-one-ref--porcelain.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook (multiple alt, no alt-ref for the 1st resp, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "alt refs/for/master/topic old-oid=$A new-oid=$B" \
    ++		-r "alt refs/for/master/topic refs/changes/24/124/1 old-oid=$ZERO_OID new-oid=$A" \
    ++		-r "alt refs/for/master/topic refs/changes/25/125/1 old-oid=$A new-oid=$B"
    ++	EOF
     +'
     +
    -+# Refs of upstream : master(A)             refs/for/master/topic(A)
    ++# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
    -+test_expect_success "cleanup" '
    -+	git -C "$upstream" update-ref -d refs/for/master/topic
    ++# git push         :                       refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report multiple alt, no alt-ref for the 1st resp (--porcelain, $PROTOCOL)" '
    ++	git -C workbench push --porcelain origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic old-oid=<COMMIT-A> new-oid=<COMMIT-B>
    ++	remote: proc-receive> alt refs/for/master/topic refs/changes/24/124/1 old-oid=<ZERO-OID> new-oid=<COMMIT-A>
    ++	remote: proc-receive> alt refs/for/master/topic refs/changes/25/125/1 old-oid=<COMMIT-A> new-oid=<COMMIT-B>
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	*    HEAD:refs/for/master/topic    [new reference]
    ++	Done
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
     +'
     +
    -+test_expect_success "setup proc-receive hook (with extended status)" '
    ++test_expect_success "setup proc-receive hook (multiple alt, no alt-ref for the 2nd resp, $PROTOCOL)" '
     +	write_script "$upstream/hooks/proc-receive" <<-EOF
     +	printf >&2 "# proc-receive hook\n"
     +	test-tool proc-receive -v \
    -+		-r "ok refs/for/a/b/c/topic" \
    -+		-r "alt refs/for/next/topic refs/pull/123/head" \
    -+		-r "alt refs/for/master/topic refs/pull/124/head old-oid=$B forced-update new-oid=$A"
    ++		-r "alt refs/for/master/topic refs/changes/24/124/1 old-oid=$ZERO_OID new-oid=$A" \
    ++		-r "alt refs/for/master/topic old-oid=$A new-oid=$B" \
    ++		-r "alt refs/for/master/topic refs/changes/25/125/1 old-oid=$B new-oid=$A forced-update"
     +	EOF
     +'
     +
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
    -+# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    -+test_expect_success "proc-receive: report with extended status" '
    -+	git -C workbench push origin \
    -+		HEAD:refs/for/next/topic \
    -+		HEAD:refs/for/a/b/c/topic \
    ++# git push         :                       refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report multiple alt, no alt-ref for the 2nd resp (--porcelain, $PROTOCOL)" '
    ++	git -C workbench push --porcelain origin \
     +		HEAD:refs/for/master/topic \
     +		>out 2>&1 &&
     +	make_user_friendly_and_stable_output <out >actual &&
     +	cat >expect <<-EOF &&
     +	remote: # pre-receive hook
    -+	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    -+	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
     +	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
     +	remote: # proc-receive hook
    -+	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    -+	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
     +	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    -+	remote: proc-receive> ok refs/for/a/b/c/topic
    -+	remote: proc-receive> alt refs/for/next/topic refs/pull/123/head
    -+	remote: proc-receive> alt refs/for/master/topic refs/pull/124/head old-oid=<COMMIT-B> forced-update new-oid=<COMMIT-A>
    ++	remote: proc-receive> alt refs/for/master/topic refs/changes/24/124/1 old-oid=<ZERO-OID> new-oid=<COMMIT-A>
    ++	remote: proc-receive> alt refs/for/master/topic old-oid=<COMMIT-A> new-oid=<COMMIT-B>
    ++	remote: proc-receive> alt refs/for/master/topic refs/changes/25/125/1 old-oid=<COMMIT-B> new-oid=<COMMIT-A> forced-update
     +	remote: # post-receive hook
    -+	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    -+	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
     +	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
     +	To <URL/of/upstream.git>
    -+	 * [new reference] HEAD -> refs/for/next/topic
    -+	 * [new reference] HEAD -> refs/for/a/b/c/topic
    -+	 * [new reference] HEAD -> refs/for/master/topic
    ++	*    HEAD:refs/for/master/topic    [new reference]
    ++	Done
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++test_expect_success "setup proc-receive hook (ok and alt for the same ref, $PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ok refs/for/master/topic" \
    ++		-r "alt refs/for/master/topic refs/changes/24/124/1 new-oid=$B old-oid=$A"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         :                       refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report ok and alt for the same ref (--porcelain, $PROTOCOL)" '
    ++	git -C workbench push --porcelain origin \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> ok refs/for/master/topic
    ++	remote: proc-receive> alt refs/for/master/topic refs/changes/24/124/1 new-oid=<COMMIT-B> old-oid=<COMMIT-A>
    ++	remote: # post-receive hook
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	*    HEAD:refs/for/master/topic    [new reference]
    ++	Done
     +	EOF
     +	test_cmp expect actual &&
     +	git -C "$upstream" show-ref >out &&
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +	test_cmp expect actual
     +'
     +
    -+test_expect_success "setup proc-receive hook (multiple responses)" '
    ++test_expect_success "setup proc-receive hook (multiple responses, $PROTOCOL)" '
     +	write_script "$upstream/hooks/proc-receive" <<-EOF
     +	printf >&2 "# proc-receive hook\n"
     +	test-tool proc-receive -v \
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
     +# git push         :                       refs/for/master/topic(A)
    -+test_expect_success "proc-receive: report multiple response" '
    -+	git -C workbench push origin \
    ++test_expect_success "proc-receive: report multiple response (--porcelain, $PROTOCOL)" '
    ++	git -C workbench push --porcelain origin \
     +		HEAD:refs/for/master/topic \
     +		>out 2>&1 &&
     +	make_user_friendly_and_stable_output <out >actual &&
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +	remote: # post-receive hook
     +	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
     +	To <URL/of/upstream.git>
    -+	 * [new reference] HEAD -> refs/for/master/topic
    ++	*    HEAD:refs/for/master/topic    [new reference]
    ++	Done
     +	EOF
     +	test_cmp expect actual &&
     +	git -C "$upstream" show-ref >out &&
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +	EOF
     +	test_cmp expect actual
     +'
    -+
    -+test_expect_success "setup proc-receive hook" '
    +
    + ## t/t5411/test-0038-report-mixed-refs.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook ($PROTOCOL)" '
     +	write_script "$upstream/hooks/proc-receive" <<-EOF
     +	printf >&2 "# proc-receive hook\n"
     +	test-tool proc-receive -v \
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +# Refs of upstream : master(A)
     +# Refs of workbench: master(A)  tags/v123
     +# git push         : (B)                   bar(A)  baz(A)  refs/for/next/topic(A)  foo(A)  refs/for/master/topic(A)
    -+test_expect_success "proc-receive: report update of mixed refs" '
    ++test_expect_success "proc-receive: report update of mixed refs ($PROTOCOL)" '
     +	git -C workbench push origin \
     +		$B:refs/heads/master \
     +		HEAD:refs/heads/bar \
    @@ t/t5411/common-test-cases.sh: test_expect_success "normal git-push command" '
     +	EOF
     +	test_cmp expect actual
     +'
    ++
    ++# Refs of upstream : master(B)             foo(A)  bar(A))  baz(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++test_expect_success "cleanup ($PROTOCOL)" '
    ++	(
    ++		cd "$upstream" &&
    ++		git update-ref refs/heads/master $A &&
    ++		git update-ref -d refs/heads/foo &&
    ++		git update-ref -d refs/heads/bar &&
    ++		git update-ref -d refs/heads/baz
    ++	)
    ++
    ++'
    +
    + ## t/t5411/test-0039-report-mixed-refs--porcelain.sh (new) ##
    +@@
    ++test_expect_success "setup proc-receive hook ($PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ok refs/for/next/topic" \
    ++		-r "alt refs/for/master/topic refs/for/master/topic old-oid=$A new-oid=$B"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push         : (B)                   bar(A)  baz(A)  refs/for/next/topic(A)  foo(A)  refs/for/master/topic(A)
    ++test_expect_success "proc-receive: report update of mixed refs (--porcelain, $PROTOCOL)" '
    ++	git -C workbench push --porcelain origin \
    ++		$B:refs/heads/master \
    ++		HEAD:refs/heads/bar \
    ++		HEAD:refs/heads/baz \
    ++		HEAD:refs/for/next/topic \
    ++		HEAD:refs/heads/foo \
    ++		HEAD:refs/for/master/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/bar
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/baz
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive> ok refs/for/next/topic
    ++	remote: proc-receive> alt refs/for/master/topic refs/for/master/topic old-oid=<COMMIT-A> new-oid=<COMMIT-B>
    ++	remote: # post-receive hook
    ++	remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/bar
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/baz
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo
    ++	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	To <URL/of/upstream.git>
    ++	     <COMMIT-B>:refs/heads/master    <OID-A>..<OID-B>
    ++	*    HEAD:refs/heads/bar    [new branch]
    ++	*    HEAD:refs/heads/baz    [new branch]
    ++	*    HEAD:refs/for/next/topic    [new reference]
    ++	*    HEAD:refs/heads/foo    [new branch]
    ++	*    HEAD:refs/for/master/topic    [new reference]
    ++	Done
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-A> refs/heads/bar
    ++	<COMMIT-A> refs/heads/baz
    ++	<COMMIT-A> refs/heads/foo
    ++	<COMMIT-B> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++# Refs of upstream : master(B)             foo(A)  bar(A))  baz(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++test_expect_success "cleanup ($PROTOCOL)" '
    ++	(
    ++		cd "$upstream" &&
    ++		git update-ref refs/heads/master $A &&
    ++		git update-ref -d refs/heads/foo &&
    ++		git update-ref -d refs/heads/bar &&
    ++		git update-ref -d refs/heads/baz
    ++	)
    ++
    ++'
4:  d20702291b ! 4:  f03038c82f send-pack: extension for client-side status report
    @@ remote.c: void apply_push_cas(struct push_cas_option *cas,
     +void update_ref_from_remote_status(struct ref *ref)
     +{
     +	char *val;
    -+	char c;
     +	int len;
     +
     +	if (!ref->remote_status)
     +		return;
     +
     +	val = (char *)parse_feature_value(ref->remote_status, "old-oid", &len);
    -+	if (val && len) {
    -+		c = *(val+len);
    -+		*(val+len) = '\0';
    ++	if (val && len)
     +		get_oid_hex(val, &ref->old_oid);
    -+		*(val+len) = c;
    -+	}
    ++
     +	val = (char *)parse_feature_value(ref->remote_status, "new-oid", &len);
    -+	if (val && len) {
    -+		c = *(val+len);
    -+		*(val+len) = '\0';
    ++	if (val && len)
     +		get_oid_hex(val, &ref->new_oid);
    -+		*(val+len) = c;
    -+	}
    ++
     +	if (parse_feature_request(ref->remote_status, "forced-update"))
     +		ref->forced_update = 1;
     +}
    @@ send-pack.c: static int receive_status(struct packet_reader *reader, struct ref
      		/* first try searching at our hint, falling back to all refs */
      		if (hint)
     @@ send-pack.c: static int receive_status(struct packet_reader *reader, struct ref *refs)
    + 			hint->status = REF_STATUS_OK;
    + 		else
      			hint->status = REF_STATUS_REMOTE_REJECT;
    - 			ret = -1;
    - 		}
     -		hint->remote_status = xstrdup_or_null(msg);
     +		if (msg)
     +			hint->remote_status = xstrdup(msg);
     +		else if (extended_status)
    -+			hint->remote_status = xstrdup(extended_status);
    ++			hint->remote_status = xstrdup_or_null(extended_status);
      		/* start our next search from the next ref */
      		hint = hint->next;
      	}
     
    - ## t/t5411/common-test-cases.sh ##
    -@@ t/t5411/common-test-cases.sh: test_expect_success "proc-receive: report with extended status" '
    + ## t/t5411/test-0032-report-alt.sh ##
    +@@ t/t5411/test-0032-report-alt.sh: test_expect_success "proc-receive: report alt (alt <ref> <alt-ref>, $PROTOCOL)"
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	 * [new reference] HEAD -> refs/for/master/topic
    ++	 * [new reference] HEAD -> refs/pull/123/head
    + 	EOF
    + 	test_cmp expect actual
    + '
    +@@ t/t5411/test-0032-report-alt.sh: test_expect_success "proc-receive: report alt (alt <ref> <alt-ref> forced-update
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	 * [new reference] HEAD -> refs/for/master/topic
    ++	 * [new reference] HEAD -> refs/pull/123/head
    + 	EOF
    + 	test_cmp expect actual
    + '
    +@@ t/t5411/test-0032-report-alt.sh: test_expect_success "proc-receive: report alt (alt <ref> <alt-ref> old-oid=X, $P
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	 * [new reference] HEAD -> refs/for/master/topic
    ++	 <OID-B>..<OID-A> HEAD -> refs/pull/123/head
    + 	EOF
    + 	test_cmp expect actual
    + '
    +@@ t/t5411/test-0032-report-alt.sh: test_expect_success "proc-receive: report alt (alt <ref> old-oid=X, $PROTOCOL)"
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	 * [new reference] HEAD -> refs/for/master/topic
    ++	 <OID-B>..<OID-A> HEAD -> refs/for/master/topic
    + 	EOF
    + 	test_cmp expect actual
    + '
    +@@ t/t5411/test-0032-report-alt.sh: test_expect_success "proc-receive: report alt (alt <ref> old-oid=X new-oid=Y, $P
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	 * [new reference] HEAD -> refs/for/master/topic
    ++	 <OID-A>..<OID-B> HEAD -> refs/for/master/topic
    + 	EOF
    + 	test_cmp expect actual
    + '
    +@@ t/t5411/test-0032-report-alt.sh: test_expect_success "proc-receive: with multiple alt reports ($PROTOCOL)" '
      	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
      	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
      	To <URL/of/upstream.git>
    @@ t/t5411/common-test-cases.sh: test_expect_success "proc-receive: report with ext
     +	 + <OID-B>...<OID-A> HEAD -> refs/pull/124/head (forced update)
      	EOF
      	test_cmp expect actual &&
    + 
    +
    + ## t/t5411/test-0033-report-alt--porcelain.sh ##
    +@@ t/t5411/test-0033-report-alt--porcelain.sh: test_expect_success "proc-receive: report alt (alt <ref> <alt-ref>, --porcelain,
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	*    HEAD:refs/for/master/topic    [new reference]
    ++	*    HEAD:refs/pull/123/head    [new reference]
    + 	Done
    + 	EOF
    + 	test_cmp expect actual
    +@@ t/t5411/test-0033-report-alt--porcelain.sh: test_expect_success "proc-receive: report alt (alt <ref> <alt-ref> forced-update
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	*    HEAD:refs/for/master/topic    [new reference]
    ++	*    HEAD:refs/pull/123/head    [new reference]
    + 	Done
    + 	EOF
    + 	test_cmp expect actual
    +@@ t/t5411/test-0033-report-alt--porcelain.sh: test_expect_success "proc-receive: report alt (alt <ref> <alt-ref> old-oid=X, --
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	*    HEAD:refs/for/master/topic    [new reference]
    ++	     HEAD:refs/pull/123/head    <OID-B>..<OID-A>
    + 	Done
    + 	EOF
    + 	test_cmp expect actual
    +@@ t/t5411/test-0033-report-alt--porcelain.sh: test_expect_success "proc-receive: report alt (alt <ref> old-oid=X, --porcelain,
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	*    HEAD:refs/for/master/topic    [new reference]
    ++	     HEAD:refs/for/master/topic    <OID-B>..<OID-A>
    + 	Done
    + 	EOF
    + 	test_cmp expect actual
    +@@ t/t5411/test-0033-report-alt--porcelain.sh: test_expect_success "proc-receive: report alt (alt <ref> old-oid=X new-oid=Y, --
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	*    HEAD:refs/for/master/topic    [new reference]
    ++	     HEAD:refs/for/master/topic    <OID-A>..<OID-B>
    + 	Done
    + 	EOF
    + 	test_cmp expect actual
    +@@ t/t5411/test-0033-report-alt--porcelain.sh: test_expect_success "proc-receive: with multiple alt reports (--porcelain, $PROT
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	*    HEAD:refs/for/next/topic    [new reference]
    ++	*    HEAD:refs/pull/123/head    [new reference]
    + 	*    HEAD:refs/for/a/b/c/topic    [new reference]
    +-	*    HEAD:refs/for/master/topic    [new reference]
    ++	+    HEAD:refs/pull/124/head    <OID-B>...<OID-A> (forced update)
    + 	Done
    + 	EOF
    + 	test_cmp expect actual &&
    +
    + ## t/t5411/test-0036-report-multi-alt-for-one-ref.sh ##
    +@@ t/t5411/test-0036-report-multi-alt-for-one-ref.sh: test_expect_success "proc-receive: report multiple alt, no alt-ref for the 1st r
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	 * [new reference] HEAD -> refs/for/master/topic
    ++	 <OID-A>..<OID-B> HEAD -> refs/for/master/topic
    ++	 * [new reference] HEAD -> refs/changes/24/124/1
    ++	 <OID-A>..<OID-B> HEAD -> refs/changes/25/125/1
    + 	EOF
    + 	test_cmp expect actual &&
      	git -C "$upstream" show-ref >out &&
    -@@ t/t5411/common-test-cases.sh: test_expect_success "proc-receive: report multiple response" '
    +@@ t/t5411/test-0036-report-multi-alt-for-one-ref.sh: test_expect_success "proc-receive: report multiple alt, no alt-ref for the 2nd r
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	 * [new reference] HEAD -> refs/for/master/topic
    ++	 * [new reference] HEAD -> refs/changes/24/124/1
    ++	 <OID-A>..<OID-B> HEAD -> refs/for/master/topic
    ++	 + <OID-B>...<OID-A> HEAD -> refs/changes/25/125/1 (forced update)
    + 	EOF
    + 	test_cmp expect actual &&
    + 	git -C "$upstream" show-ref >out &&
    +@@ t/t5411/test-0036-report-multi-alt-for-one-ref.sh: test_expect_success "proc-receive: report ok and alt for the same ref ($PROTOCOL
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    + 	 * [new reference] HEAD -> refs/for/master/topic
    ++	 <OID-A>..<OID-B> HEAD -> refs/changes/24/124/1
    + 	EOF
    + 	test_cmp expect actual &&
    + 	git -C "$upstream" show-ref >out &&
    +@@ t/t5411/test-0036-report-multi-alt-for-one-ref.sh: test_expect_success "proc-receive: report multiple response ($PROTOCOL)" '
      	remote: # post-receive hook
      	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
      	To <URL/of/upstream.git>
    @@ t/t5411/common-test-cases.sh: test_expect_success "proc-receive: report multiple
      	EOF
      	test_cmp expect actual &&
      	git -C "$upstream" show-ref >out &&
    -@@ t/t5411/common-test-cases.sh: test_expect_success "proc-receive: report update of mixed refs" '
    +
    + ## t/t5411/test-0037-report-multi-alt-for-one-ref--porcelain.sh ##
    +@@ t/t5411/test-0037-report-multi-alt-for-one-ref--porcelain.sh: test_expect_success "proc-receive: report multiple alt, no alt-ref for the 1st r
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	*    HEAD:refs/for/master/topic    [new reference]
    ++	     HEAD:refs/for/master/topic    <OID-A>..<OID-B>
    ++	*    HEAD:refs/changes/24/124/1    [new reference]
    ++	     HEAD:refs/changes/25/125/1    <OID-A>..<OID-B>
    + 	Done
    + 	EOF
    + 	test_cmp expect actual &&
    +@@ t/t5411/test-0037-report-multi-alt-for-one-ref--porcelain.sh: test_expect_success "proc-receive: report multiple alt, no alt-ref for the 2nd r
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	*    HEAD:refs/for/master/topic    [new reference]
    ++	*    HEAD:refs/changes/24/124/1    [new reference]
    ++	     HEAD:refs/for/master/topic    <OID-A>..<OID-B>
    ++	+    HEAD:refs/changes/25/125/1    <OID-B>...<OID-A> (forced update)
    + 	Done
    + 	EOF
    + 	test_cmp expect actual &&
    +@@ t/t5411/test-0037-report-multi-alt-for-one-ref--porcelain.sh: test_expect_success "proc-receive: report ok and alt for the same ref (--porcela
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    + 	*    HEAD:refs/for/master/topic    [new reference]
    ++	     HEAD:refs/changes/24/124/1    <OID-A>..<OID-B>
    + 	Done
    + 	EOF
    + 	test_cmp expect actual &&
    +@@ t/t5411/test-0037-report-multi-alt-for-one-ref--porcelain.sh: test_expect_success "proc-receive: report multiple response (--porcelain, $PROTO
    + 	remote: # post-receive hook
    + 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    + 	To <URL/of/upstream.git>
    +-	*    HEAD:refs/for/master/topic    [new reference]
    ++	*    HEAD:refs/changes/23/123/1    [new reference]
    ++	     HEAD:refs/changes/24/124/2    <OID-A>..<OID-B>
    + 	Done
    + 	EOF
    + 	test_cmp expect actual &&
    +
    + ## t/t5411/test-0038-report-mixed-refs.sh ##
    +@@ t/t5411/test-0038-report-mixed-refs.sh: test_expect_success "proc-receive: report update of mixed refs ($PROTOCOL)" '
      	 * [new branch] HEAD -> baz
      	 * [new reference] HEAD -> refs/for/next/topic
      	 * [new branch] HEAD -> foo
    @@ t/t5411/common-test-cases.sh: test_expect_success "proc-receive: report update o
      	test_cmp expect actual &&
      	git -C "$upstream" show-ref >out &&
     
    + ## t/t5411/test-0039-report-mixed-refs--porcelain.sh ##
    +@@ t/t5411/test-0039-report-mixed-refs--porcelain.sh: test_expect_success "proc-receive: report update of mixed refs (--porcelain, $PR
    + 	*    HEAD:refs/heads/baz    [new branch]
    + 	*    HEAD:refs/for/next/topic    [new reference]
    + 	*    HEAD:refs/heads/foo    [new branch]
    +-	*    HEAD:refs/for/master/topic    [new reference]
    ++	     HEAD:refs/for/master/topic    <OID-A>..<OID-B>
    + 	Done
    + 	EOF
    + 	test_cmp expect actual &&
    +
      ## transport-helper.c ##
     @@ transport-helper.c: static int push_update_ref_status(struct strbuf *buf,
      			msg = xstrdup(msg);
    @@ transport.c: static void print_ref_status(char flag, const char *summary,
     +	if (to && to->remote_status) {
     +		val = parse_feature_value(to->remote_status, "ref", &len);
     +		if (val && len)
    -+		to_name = xmemdupz(val, len);
    ++			to_name = xmemdupz(val, len);
     +	}
     +
      	if (porcelain) {
    @@ transport.c: static int print_one_push_status(struct ref *ref, const char *dest,
     +					      porcelain, summary_width);
     +
     +	head = ref->remote_status;
    -+	begin = strstr(head, "ref=");
    -+	if (!begin)
    -+		begin = ref->remote_status;
    ++	begin = head;
     +	for (;;) {
     +		char *end;
     +		struct object_id old_oid;
-:  ---------- > 5:  c3ad1ab5a4 receive-pack: feed extended_status to post-receive
5:  a8860faa17 = 6:  d9226a4898 refs.c: refactor to reuse ref_is_hidden()
6:  46a839ddf6 ! 7:  7143e2c501 receive-pack: new config receive.procReceiveRefs
    @@ builtin/receive-pack.c: static void execute_commands(struct command *commands,
     +	if (proc_receive_refs.nr > 0) {
     +		struct strbuf refname_full = STRBUF_INIT;
     +		size_t prefix_len;
    -+
    -+		strbuf_addstr(&refname_full, get_git_namespace());
    -+		prefix_len = refname_full.len;
      
     -		/* TODO: replace the fixed prefix by looking up git config variables. */
     -		if (!strncmp(cmd->ref_name, "refs/for/", 9)) {
     -			cmd->run_proc_receive = RUN_PROC_RECEIVE_SCHEDULED;
     -			run_proc_receive = 1;
    ++		strbuf_addstr(&refname_full, get_git_namespace());
    ++		prefix_len = refname_full.len;
    ++
     +		for (cmd = commands; cmd; cmd = cmd->next) {
     +			if (!should_process_cmd(cmd))
     +				continue;
    @@ builtin/receive-pack.c: int cmd_receive_pack(int argc, const char **argv, const
      	return 0;
      }
     
    - ## t/t5411/common-test-cases.sh ##
    -@@ t/t5411/common-test-cases.sh: test_expect_success "cleanup" '
    - 	)
    - '
    - 
    + ## t/t5411/test-0010-proc-receive-settings.sh (new) ##
    +@@
     +test_expect_success "add two receive.procReceiveRefs settings" '
     +	(
     +		cd "$upstream" &&
     +		git config --add receive.procReceiveRefs refs/for &&
     +		git config --add receive.procReceiveRefs refs/review/
     +	)
    ++'
    +
    + ## t/t5411/test-0040-process-all-refs.sh (new) ##
    +@@
    ++test_expect_success "config receive.procReceiveRefs = refs ($PROTOCOL)" '
    ++	git -C "$upstream" config --unset-all receive.procReceiveRefs &&
    ++	git -C "$upstream" config --add receive.procReceiveRefs refs
     +'
     +
    - # Refs of upstream : master(A)
    - # Refs of workbench: master(A)  tags/v123
    - # git push         :                       next(A)  refs/for/master/topic(A)
    -@@ t/t5411/common-test-cases.sh: test_expect_success "setup proc-receive hook (with extended status)" '
    - 	write_script "$upstream/hooks/proc-receive" <<-EOF
    - 	printf >&2 "# proc-receive hook\n"
    - 	test-tool proc-receive -v \
    --		-r "ok refs/for/a/b/c/topic" \
    -+		-r "ok refs/review/a/b/c/topic" \
    - 		-r "alt refs/for/next/topic refs/pull/123/head" \
    - 		-r "alt refs/for/master/topic refs/pull/124/head old-oid=$B forced-update new-oid=$A"
    - 	EOF
    -@@ t/t5411/common-test-cases.sh: test_expect_success "setup proc-receive hook (with extended status)" '
    - 
    - # Refs of upstream : master(A)
    - # Refs of workbench: master(A)  tags/v123
    --# git push         :                       refs/for/next/topic(A)  refs/for/a/b/c/topic(A)  refs/for/master/topic(A)
    -+# git push         :                       refs/for/next/topic(A)  refs/review/a/b/c/topic(A)  refs/for/master/topic(A)
    - test_expect_success "proc-receive: report with extended status" '
    - 	git -C workbench push origin \
    - 		HEAD:refs/for/next/topic \
    --		HEAD:refs/for/a/b/c/topic \
    -+		HEAD:refs/review/a/b/c/topic \
    - 		HEAD:refs/for/master/topic \
    - 		>out 2>&1 &&
    - 	make_user_friendly_and_stable_output <out >actual &&
    - 	cat >expect <<-EOF &&
    - 	remote: # pre-receive hook
    - 	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    --	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
    -+	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/review/a/b/c/topic
    - 	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    - 	remote: # proc-receive hook
    - 	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    --	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
    -+	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/review/a/b/c/topic
    - 	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    --	remote: proc-receive> ok refs/for/a/b/c/topic
    -+	remote: proc-receive> ok refs/review/a/b/c/topic
    - 	remote: proc-receive> alt refs/for/next/topic refs/pull/123/head
    - 	remote: proc-receive> alt refs/for/master/topic refs/pull/124/head old-oid=<COMMIT-B> forced-update new-oid=<COMMIT-A>
    - 	remote: # post-receive hook
    - 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    --	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
    -+	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/review/a/b/c/topic
    - 	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    - 	To <URL/of/upstream.git>
    - 	 * [new reference] HEAD -> refs/pull/123/head
    --	 * [new reference] HEAD -> refs/for/a/b/c/topic
    -+	 * [new reference] HEAD -> refs/review/a/b/c/topic
    - 	 + <OID-B>...<OID-A> HEAD -> refs/pull/124/head (forced update)
    - 	EOF
    - 	test_cmp expect actual &&
    -@@ t/t5411/common-test-cases.sh: test_expect_success "proc-receive: report update of mixed refs" '
    - 	EOF
    - 	test_cmp expect actual
    - '
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++test_expect_success "setup upstream branches ($PROTOCOL)" '
    ++	(
    ++		cd "$upstream" &&
    ++		git update-ref refs/heads/master $B &&
    ++		git update-ref refs/heads/foo $A &&
    ++		git update-ref refs/heads/bar $A &&
    ++		git update-ref refs/heads/baz $A
    ++	)
     +
    -+test_expect_success "config add receive.procReceiveRefs = refs" '
    -+	git -C "$upstream" config --add receive.procReceiveRefs refs
     +'
     +
    -+test_expect_success "setup proc-receive hook" '
    ++test_expect_success "setup proc-receive hook ($PROTOCOL)" '
     +	write_script "$upstream/hooks/proc-receive" <<-EOF
     +	printf >&2 "# proc-receive hook\n"
     +	test-tool proc-receive -v \
    @@ t/t5411/common-test-cases.sh: test_expect_success "proc-receive: report update o
     +# Refs of upstream : master(B)             foo(A)  bar(A))  baz(A)
     +# Refs of workbench: master(A)  tags/v123
     +# git push -f      : master(A)             (NULL)  (B)              refs/for/master/topic(A)  refs/for/next/topic(A)
    -+test_expect_success "proc-receive: process all refs" '
    ++test_expect_success "proc-receive: process all refs ($PROTOCOL)" '
     +	git -C workbench push -f origin \
     +		HEAD:refs/heads/master \
     +		:refs/heads/foo \
    @@ t/t5411/common-test-cases.sh: test_expect_success "proc-receive: report update o
     +	remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar
     +	remote: post-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo
     +	remote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
    -+	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    -+	remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    ++	remote: post-receive< <COMMIT-A> <COMMIT-B> refs/pull/123/head
    ++	remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/124/head
     +	To <URL/of/upstream.git>
     +	 <OID-A>..<OID-B> <COMMIT-B> -> bar
     +	 - [deleted] foo
    @@ t/t5411/common-test-cases.sh: test_expect_success "proc-receive: report update o
     +	EOF
     +	test_cmp expect actual
     +'
    ++
    ++# Refs of upstream : master(A)             bar(A)  baz(B)
    ++# Refs of workbench: master(A)  tags/v123
    ++test_expect_success "cleanup ($PROTOCOL)" '
    ++	(
    ++		cd "$upstream" &&
    ++		git update-ref -d refs/heads/bar &&
    ++		git update-ref -d refs/heads/baz
    ++	)
    ++'
    +
    + ## t/t5411/test-0041-process-all-refs--porcelain.sh (new) ##
    +@@
    ++test_expect_success "config receive.procReceiveRefs = refs ($PROTOCOL)" '
    ++	git -C "$upstream" config --unset-all receive.procReceiveRefs &&
    ++	git -C "$upstream" config --add receive.procReceiveRefs refs
    ++'
    ++
    ++# Refs of upstream : master(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++test_expect_success "setup upstream branches ($PROTOCOL)" '
    ++	(
    ++		cd "$upstream" &&
    ++		git update-ref refs/heads/master $B &&
    ++		git update-ref refs/heads/foo $A &&
    ++		git update-ref refs/heads/bar $A &&
    ++		git update-ref refs/heads/baz $A
    ++	)
    ++
    ++'
    ++
    ++test_expect_success "setup proc-receive hook ($PROTOCOL)" '
    ++	write_script "$upstream/hooks/proc-receive" <<-EOF
    ++	printf >&2 "# proc-receive hook\n"
    ++	test-tool proc-receive -v \
    ++		-r "ft refs/heads/master" \
    ++		-r "ft refs/heads/foo" \
    ++		-r "ft refs/heads/bar" \
    ++		-r "alt refs/for/master/topic refs/pull/123/head old-oid=$A new-oid=$B " \
    ++		-r "alt refs/for/next/topic refs/pull/124/head old-oid=$B new-oid=$A forced-update"
    ++	EOF
    ++'
    ++
    ++# Refs of upstream : master(B)             foo(A)  bar(A))  baz(A)
    ++# Refs of workbench: master(A)  tags/v123
    ++# git push -f      : master(A)             (NULL)  (B)              refs/for/master/topic(A)  refs/for/next/topic(A)
    ++test_expect_success "proc-receive: process all refs (--porcelain) ($PROTOCOL)" '
    ++	git -C workbench push --porcelain -f origin \
    ++		HEAD:refs/heads/master \
    ++		:refs/heads/foo \
    ++		$B:refs/heads/bar \
    ++		HEAD:refs/for/master/topic \
    ++		HEAD:refs/for/next/topic \
    ++		>out 2>&1 &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	remote: # pre-receive hook
    ++	remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar
    ++	remote: pre-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo
    ++	remote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    ++	remote: # proc-receive hook
    ++	remote: proc-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar
    ++	remote: proc-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo
    ++	remote: proc-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
    ++	remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
    ++	remote: proc-receive> ft refs/heads/master
    ++	remote: proc-receive> ft refs/heads/foo
    ++	remote: proc-receive> ft refs/heads/bar
    ++	remote: proc-receive> alt refs/for/master/topic refs/pull/123/head old-oid=<COMMIT-A> new-oid=<COMMIT-B>
    ++	remote: proc-receive> alt refs/for/next/topic refs/pull/124/head old-oid=<COMMIT-B> new-oid=<COMMIT-A> forced-update
    ++	remote: # post-receive hook
    ++	remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar
    ++	remote: post-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo
    ++	remote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
    ++	remote: post-receive< <COMMIT-A> <COMMIT-B> refs/pull/123/head
    ++	remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/124/head
    ++	To <URL/of/upstream.git>
    ++	     <COMMIT-B>:refs/heads/bar    <OID-A>..<OID-B>
    ++	-    :refs/heads/foo    [deleted]
    ++	+    HEAD:refs/heads/master    <OID-B>...<OID-A> (forced update)
    ++	     HEAD:refs/pull/123/head    <OID-A>..<OID-B>
    ++	+    HEAD:refs/pull/124/head    <OID-B>...<OID-A> (forced update)
    ++	Done
    ++	EOF
    ++	test_cmp expect actual &&
    ++	git -C "$upstream" show-ref >out &&
    ++	make_user_friendly_and_stable_output <out >actual &&
    ++	cat >expect <<-EOF &&
    ++	<COMMIT-B> refs/heads/bar
    ++	<COMMIT-A> refs/heads/baz
    ++	<COMMIT-A> refs/heads/master
    ++	EOF
    ++	test_cmp expect actual
    ++'
    ++
    ++# Refs of upstream : master(A)             bar(A)  baz(B)
    ++# Refs of workbench: master(A)  tags/v123
    ++test_expect_success "cleanup ($PROTOCOL)" '
    ++	(
    ++		cd "$upstream" &&
    ++		git update-ref -d refs/heads/bar &&
    ++		git update-ref -d refs/heads/baz
    ++	)
    ++'
7:  a357234e97 = 8:  98702cf3e9 doc: add documentation for the proc-receive hook

---

Jiang Xin (8):
  transport: not report a non-head push as a branch
  connect: export parse_feature_value()
  receive-pack: add new proc-receive hook
  send-pack: extension for client-side status report
  receive-pack: feed extended_status to post-receive
  refs.c: refactor to reuse ref_is_hidden()
  receive-pack: new config receive.procReceiveRefs
  doc: add documentation for the proc-receive hook

 Documentation/config/receive.txt              |  14 +
 Documentation/githooks.txt                    |  58 +++
 Makefile                                      |   1 +
 builtin/receive-pack.c                        | 442 +++++++++++++++++-
 connect.c                                     |   3 +-
 connect.h                                     |   1 +
 refs.c                                        |  13 +-
 refs.h                                        |   1 +
 remote.c                                      |  21 +
 remote.h                                      |   3 +
 send-pack.c                                   |  11 +-
 t/helper/test-proc-receive.c                  | 175 +++++++
 t/helper/test-tool.c                          |   1 +
 t/helper/test-tool.h                          |   1 +
 t/t5411-proc-receive-hook.sh                  | 105 +++++
 t/t5411/common-functions.sh                   |  56 +++
 t/t5411/test-0000-standard-git-push.sh        |  84 ++++
 .../test-0001-standard-git-push--porcelain.sh |  87 ++++
 t/t5411/test-0002-pre-receive-declined.sh     |  33 ++
 ...st-0003-pre-receive-declined--porcelain.sh |  34 ++
 t/t5411/test-0010-proc-receive-settings.sh    |   7 +
 t/t5411/test-0011-no-hook-error.sh            |  64 +++
 t/t5411/test-0012-no-hook-error--porcelain.sh |  66 +++
 t/t5411/test-0013-bad-protocol.sh             | 225 +++++++++
 t/t5411/test-0014-bad-protocol--porcelain.sh  | 160 +++++++
 t/t5411/test-0020-report-ng.sh                |  67 +++
 t/t5411/test-0021-report-ng--porcelain.sh     |  69 +++
 t/t5411/test-0022-report-unexpect-ref.sh      |  45 ++
 ...est-0023-report-unexpect-ref--porcelain.sh |  46 ++
 t/t5411/test-0024-report-unknown-ref.sh       |  34 ++
 ...test-0025-report-unknown-ref--porcelain.sh |  35 ++
 t/t5411/test-0026-push-options.sh             |  79 ++++
 t/t5411/test-0027-push-options--porcelain.sh  |  82 ++++
 t/t5411/test-0030-report-ok.sh                |  35 ++
 t/t5411/test-0031-report-ok--porcelain.sh     |  36 ++
 t/t5411/test-0032-report-alt.sh               | 229 +++++++++
 t/t5411/test-0033-report-alt--porcelain.sh    | 236 ++++++++++
 t/t5411/test-0034-report-ft.sh                |  42 ++
 t/t5411/test-0035-report-ft--porcelain.sh     |  43 ++
 .../test-0036-report-multi-alt-for-one-ref.sh | 167 +++++++
 ...report-multi-alt-for-one-ref--porcelain.sh | 171 +++++++
 t/t5411/test-0038-report-mixed-refs.sh        |  74 +++
 .../test-0039-report-mixed-refs--porcelain.sh |  75 +++
 t/t5411/test-0040-process-all-refs.sh         |  93 ++++
 .../test-0041-process-all-refs--porcelain.sh  |  94 ++++
 t/t5516-fetch-push.sh                         |   2 +-
 transport-helper.c                            |  64 +--
 transport.c                                   |  83 +++-
 48 files changed, 3506 insertions(+), 61 deletions(-)
 create mode 100644 t/helper/test-proc-receive.c
 create mode 100755 t/t5411-proc-receive-hook.sh
 create mode 100644 t/t5411/common-functions.sh
 create mode 100644 t/t5411/test-0000-standard-git-push.sh
 create mode 100644 t/t5411/test-0001-standard-git-push--porcelain.sh
 create mode 100644 t/t5411/test-0002-pre-receive-declined.sh
 create mode 100644 t/t5411/test-0003-pre-receive-declined--porcelain.sh
 create mode 100644 t/t5411/test-0010-proc-receive-settings.sh
 create mode 100644 t/t5411/test-0011-no-hook-error.sh
 create mode 100644 t/t5411/test-0012-no-hook-error--porcelain.sh
 create mode 100644 t/t5411/test-0013-bad-protocol.sh
 create mode 100644 t/t5411/test-0014-bad-protocol--porcelain.sh
 create mode 100644 t/t5411/test-0020-report-ng.sh
 create mode 100644 t/t5411/test-0021-report-ng--porcelain.sh
 create mode 100644 t/t5411/test-0022-report-unexpect-ref.sh
 create mode 100644 t/t5411/test-0023-report-unexpect-ref--porcelain.sh
 create mode 100644 t/t5411/test-0024-report-unknown-ref.sh
 create mode 100644 t/t5411/test-0025-report-unknown-ref--porcelain.sh
 create mode 100644 t/t5411/test-0026-push-options.sh
 create mode 100644 t/t5411/test-0027-push-options--porcelain.sh
 create mode 100644 t/t5411/test-0030-report-ok.sh
 create mode 100644 t/t5411/test-0031-report-ok--porcelain.sh
 create mode 100644 t/t5411/test-0032-report-alt.sh
 create mode 100644 t/t5411/test-0033-report-alt--porcelain.sh
 create mode 100644 t/t5411/test-0034-report-ft.sh
 create mode 100644 t/t5411/test-0035-report-ft--porcelain.sh
 create mode 100644 t/t5411/test-0036-report-multi-alt-for-one-ref.sh
 create mode 100644 t/t5411/test-0037-report-multi-alt-for-one-ref--porcelain.sh
 create mode 100644 t/t5411/test-0038-report-mixed-refs.sh
 create mode 100644 t/t5411/test-0039-report-mixed-refs--porcelain.sh
 create mode 100644 t/t5411/test-0040-process-all-refs.sh
 create mode 100644 t/t5411/test-0041-process-all-refs--porcelain.sh

-- 


  reply	other threads:[~2020-04-18 16:04 UTC|newest]

Thread overview: 266+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-04 11:33 [PATCH 0/7] New execute-commands hook for centralized workflow Jiang Xin
2020-03-04 11:33 ` [PATCH 1/7] receive-pack: new external execute-commands hook Jiang Xin
2020-03-04 11:33 ` [PATCH 2/7] receive-pack: feed all commands to post-receive Jiang Xin
2020-03-04 11:33 ` [PATCH 3/7] receive-pack: try `execute-commands --pre-receive` Jiang Xin
2020-03-04 11:33 ` [PATCH 4/7] receive-pack: read env from execute-commands output Jiang Xin
2020-03-04 11:33 ` [PATCH 5/7] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-03-04 11:33 ` [PATCH 6/7] receive-pack: new config receive.executeCommandsHookRefs Jiang Xin
2020-03-04 11:33 ` [PATCH 7/7] hook: add document and example for "execute-commands" hook Jiang Xin
2020-03-04 20:39 ` [PATCH 0/7] New execute-commands hook for centralized workflow Junio C Hamano
2020-03-05 16:51   ` Jiang Xin
2020-03-08 14:56     ` [PATCH v2 0/5] New proc-receive " Jiang Xin
2020-03-08 14:56     ` [PATCH v2 1/5] receive-pack: add new proc-receive hook Jiang Xin
2020-03-09 17:12       ` Junio C Hamano
2020-03-10  6:03         ` Jiang Xin
2020-03-13 12:23           ` [PATCH v3 0/4] New proc-receive hook for centralized workflow Jiang Xin
2020-03-22 13:18             ` [PATCH v4 0/5] " Jiang Xin
2020-03-25  5:19               ` Junio C Hamano
2020-03-22 13:18             ` [PATCH v4 1/5] transport: not report a non-head push as a branch Jiang Xin
2020-03-25  6:04               ` Junio C Hamano
2020-03-22 13:18             ` [PATCH v4 2/5] receive-pack: add new proc-receive hook Jiang Xin
2020-03-25 14:36               ` [PATCH 0/3] Never report references we not push Jiang Xin
2020-03-29 14:33                 ` [PATCH v2 0/4] " Jiang Xin
2020-03-29 14:35                   ` Jiang Xin
2020-04-16 16:24                   ` [PATCH v3 0/5] fix git-push porcelain output and atomic report issue Jiang Xin
2020-04-17  9:45                     ` [PATCH v4 " Jiang Xin
2020-04-17  9:45                     ` [PATCH v4 1/5] send-pack: fix inconsistent porcelain output Jiang Xin
2020-04-17 19:51                       ` Junio C Hamano
2020-04-17  9:45                     ` [PATCH v4 2/5] t5543: never report what we do not push Jiang Xin
2020-04-17  9:45                     ` [PATCH v4 3/5] send-pack: mark failure of atomic push properly Jiang Xin
2020-04-17  9:45                     ` [PATCH v4 4/5] transport-helper: mark failure for atomic push Jiang Xin
2020-04-17  9:45                     ` [PATCH v4 5/5] transport-helper: new method reject_atomic_push() Jiang Xin
2020-04-16 16:24                   ` [PATCH v3 1/5] send-pack: fix inconsistent porcelain output Jiang Xin
2020-04-16 16:24                   ` [PATCH v3 2/5] t5543: never report what we do not push Jiang Xin
2020-04-16 16:24                   ` [PATCH v3 3/5] send-pack: mark failure of atomic push properly Jiang Xin
2020-04-16 16:24                   ` [PATCH v3 4/5] transport-helper: mark failure for atomic push Jiang Xin
2020-04-16 16:24                   ` [PATCH v3 5/5] transport-helper: new method reject_atomic_push() Jiang Xin
2020-03-29 14:33                 ` [PATCH v2 1/4] t5543: never report what we do not push Jiang Xin
2020-03-29 14:33                 ` [PATCH v2 2/4] send-pack: mark failure of atomic push properly Jiang Xin
2020-03-29 14:33                 ` [PATCH v2 3/4] transport-helper: mark failure for atomic push Jiang Xin
2020-03-29 14:33                 ` [PATCH v2 4/4] transport-helper: new method reject_atomic_push() Jiang Xin
2020-03-25 14:36               ` [PATCH 1/3] t5543: never report what we do not push Jiang Xin
2020-03-25 15:05                 ` Junio C Hamano
2020-03-26  2:25                   ` Jiang Xin
2020-03-25 14:36               ` [PATCH 2/3] send-pack: mark failure of atomic push properly Jiang Xin
2020-03-25 15:15                 ` Junio C Hamano
2020-03-25 14:36               ` [PATCH 3/3] transport-helper: enforce atomic in push_refs_with_push Jiang Xin
2020-03-25 15:32                 ` Junio C Hamano
2020-03-22 13:18             ` [PATCH v4 3/5] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-03-22 13:18             ` [PATCH v4 4/5] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-03-22 13:18             ` [PATCH v4 5/5] receive-pack: refactor report for proc-receive Jiang Xin
2020-03-13 12:23           ` [PATCH v3 1/4] receive-pack: add new proc-receive hook Jiang Xin
2020-03-13 12:23           ` [PATCH v3 2/4] receive-pack: refactor report for proc-receive Jiang Xin
2020-03-13 12:23           ` [PATCH v3 3/4] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-03-13 12:23           ` [PATCH v3 4/4] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-03-08 14:56     ` [PATCH v2 2/5] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-03-08 15:38     ` [PATCH v2 3/5] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-03-08 15:38     ` [PATCH v2 4/5] receive-pack: read env from proc-receive output Jiang Xin
2020-03-08 15:38     ` [PATCH v2 5/5] hook: add document and example for "proc-receive" hook Jiang Xin
2020-03-30 16:57 ` [PATCH v5 0/6] New proc-receive hook for centralized workflow Jiang Xin
2020-03-30 16:57 ` [PATCH v5 1/6] transport: not report a non-head push as a branch Jiang Xin
2020-03-30 16:57 ` [PATCH v5 2/6] receive-pack: add new proc-receive hook Jiang Xin
2020-03-31  0:19   ` Junio C Hamano
2020-03-31  0:21   ` Junio C Hamano
2020-03-30 16:57 ` [PATCH v5 3/6] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-03-30 16:57 ` [PATCH v5 4/6] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-03-30 16:57 ` [PATCH v5 5/6] receive-pack: refactor report for proc-receive Jiang Xin
2020-03-30 16:57 ` [PATCH v5 6/6] doc: add documentation for the proc-receive hook Jiang Xin
2020-04-02 16:35 ` [PATCH v6 0/7] New proc-receive hook for centralized workflow Jiang Xin
2020-04-02 18:26   ` Junio C Hamano
2020-04-03 16:08     ` [PATCH v7 " Jiang Xin
2020-04-04 13:43       ` [PATCH v8 " Jiang Xin
2020-04-07 12:08         ` [PATCH v9 0/6] " Jiang Xin
2020-04-12 13:30           ` [PATCH v10 0/8] " Jiang Xin
2020-04-13 16:48             ` [PATCH v11 0/7] " Jiang Xin
2020-04-13 16:48             ` [PATCH v11 1/7] transport: not report a non-head push as a branch Jiang Xin
2020-04-13 16:48             ` [PATCH v11 2/7] connect: export parse_feature_value() Jiang Xin
2020-04-13 16:48             ` [PATCH v11 3/7] receive-pack: add new proc-receive hook Jiang Xin
2020-04-13 16:48             ` [PATCH v11 4/7] send-pack: extension for client-side status report Jiang Xin
2020-04-13 16:48             ` [PATCH v11 5/7] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-04-13 16:48             ` [PATCH v11 6/7] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-04-13 16:48             ` [PATCH v11 7/7] doc: add documentation for the proc-receive hook Jiang Xin
2020-04-12 13:30           ` [PATCH v10 1/8] transport: not report a non-head push as a branch Jiang Xin
2020-04-12 20:26             ` Junio C Hamano
2020-04-13 11:15               ` Jiang Xin
2020-04-12 13:30           ` [PATCH v10 2/8] receive-pack: add new proc-receive hook Jiang Xin
2020-04-12 21:30             ` Junio C Hamano
2020-04-13 10:58               ` Jiang Xin
2020-04-13 21:50                 ` Junio C Hamano
2020-04-14 12:32                   ` [PATCH v12 0/7] New proc-receive hook for centralized workflow Jiang Xin
2020-04-18 16:03                     ` Jiang Xin [this message]
2020-04-18 16:03                     ` [PATCH v13 1/8] transport: not report a non-head push as a branch Jiang Xin
2020-04-18 16:03                     ` [PATCH v13 2/8] connect: export parse_feature_value() Jiang Xin
2020-04-18 16:03                     ` [PATCH v13 3/8] receive-pack: add new proc-receive hook Jiang Xin
2020-04-18 16:03                     ` [PATCH v13 4/8] send-pack: extension for client-side status report Jiang Xin
2020-04-18 16:03                     ` [PATCH v13 5/8] receive-pack: feed extended_status to post-receive Jiang Xin
2020-04-18 16:03                     ` [PATCH v13 6/8] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-04-18 16:03                     ` [PATCH v13 7/8] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-04-18 16:03                     ` [PATCH v13 8/8] doc: add documentation for the proc-receive hook Jiang Xin
2020-04-14 12:32                   ` [PATCH v12 1/7] transport: not report a non-head push as a branch Jiang Xin
2020-04-14 12:32                   ` [PATCH v12 2/7] connect: export parse_feature_value() Jiang Xin
2020-04-14 12:32                   ` [PATCH v12 3/7] receive-pack: add new proc-receive hook Jiang Xin
2020-04-15 15:48                     ` Junio C Hamano
2020-04-15 15:55                       ` Jiang Xin
2020-04-15 18:34                         ` Junio C Hamano
2020-04-27 17:00                           ` Jiang Xin
2020-04-29  7:56                             ` Jeff King
2020-04-30 15:33                               ` Jiang Xin
2020-05-05 14:41                                 ` [PATCH v14 0/7] New proc-receive hook for centralized workflow Jiang Xin
2020-05-06 23:14                                   ` Junio C Hamano
2020-05-07  1:37                                     ` Jiang Xin
2020-05-07 11:18                                       ` Jiang Xin
2020-05-07 16:10                                     ` [PATCH v15 " Jiang Xin
2020-05-18  9:40                                       ` [PATCH v16 00/11] " Jiang Xin
2020-08-15 17:17                                         ` [PATCH v17 00/10] " Jiang Xin
2020-08-24 17:41                                           ` [PATCH v18 " Jiang Xin
2020-08-27 15:45                                             ` [PATCH v19 " Jiang Xin
2020-08-27 19:57                                               ` Junio C Hamano
2020-08-27 15:45                                             ` [PATCH v19 01/10] transport: not report a non-head push as a branch Jiang Xin
2020-08-27 15:45                                             ` [PATCH v19 02/10] t5411: add basic test cases for proc-receive hook Jiang Xin
2020-08-27 15:45                                             ` [PATCH v19 03/10] receive-pack: add new " Jiang Xin
2020-11-04 22:15                                               ` Johannes Schindelin
2020-11-04 22:58                                                 ` Johannes Schindelin
2020-11-05 14:54                                                 ` Jiang Xin
2020-11-05 15:23                                                   ` [RFC PATCH] t5411: fix broken pipe write error on proc-receive Jiang Xin
2020-11-05 19:14                                                     ` Junio C Hamano
2020-11-07  2:57                                                       ` [PATCH] t5411: consistent result for proc-receive broken test Jiang Xin
2020-11-09  7:29                                                         ` Jiang Xin
2020-11-09 10:58                                                           ` [PATCH v2] " Jiang Xin
2020-11-09 20:59                                                             ` Junio C Hamano
2020-11-09 23:12                                                               ` Jeff King
2020-11-09 23:22                                                                 ` Junio C Hamano
2020-11-10  0:03                                                                   ` Jeff King
2020-11-10 11:49                                                                 ` Jiang Xin
2020-11-10 12:01                                                                   ` [PATCH v3 1/2] t5411: refactor make_user_friendly_and_stable_output Jiang Xin
2020-11-10 20:51                                                                     ` Junio C Hamano
2020-11-11 11:08                                                                       ` Jiang Xin
2020-11-10 12:01                                                                   ` [PATCH v3 2/2] receive-pack: gently write messages to proc-receive Jiang Xin
2020-11-10 21:52                                                                     ` Jeff King
2020-11-11 11:03                                                                       ` Jiang Xin
2020-11-10 21:00                                                                   ` [PATCH v2] t5411: consistent result for proc-receive broken test Junio C Hamano
2020-11-10 21:13                                                                     ` Junio C Hamano
2020-11-11 11:31                                                                   ` [PATCH v4 0/3] jx/t5411-flake-fix Jiang Xin
2020-11-11 11:32                                                                   ` [PATCH v4 1/3] t5411: new helper filter_out_user_friendly_and_stable_output Jiang Xin
2020-11-11 11:32                                                                   ` [PATCH v4 2/3] receive-pack: gently write messages to proc-receive Jiang Xin
2020-11-11 11:32                                                                   ` [PATCH v4 3/3] receive-pack: use default version 0 for proc-receive Jiang Xin
2020-11-10 11:44                                                               ` [PATCH v2] t5411: consistent result for proc-receive broken test Jiang Xin
2020-11-05 18:39                                                   ` [PATCH v19 03/10] receive-pack: add new proc-receive hook Junio C Hamano
2021-01-17 22:21                                               ` SZEDER Gábor
2021-01-18  8:24                                                 ` Jiang Xin
2021-01-20 12:28                                                   ` SZEDER Gábor
2021-01-21  2:21                                                     ` Jiang Xin
2021-01-21  6:12                                                       ` SZEDER Gábor
2021-01-18 13:30                                                 ` [PATCH 1/2] t5411: remove file after use to prevent overwriting Jiang Xin
2021-01-18 18:21                                                   ` Johannes Sixt
2021-01-19  0:48                                                     ` Jiang Xin
2021-01-19 10:24                                                     ` [PATCH v2 0/2] t5411 out file overwrite fix Jiang Xin
2021-01-19 10:24                                                     ` [PATCH v2 1/2] t5411: use different out file to prevent overwriting Jiang Xin
2021-01-20 12:49                                                       ` SZEDER Gábor
2021-01-21  1:59                                                         ` Jiang Xin
2021-01-21  2:53                                                         ` [PATCH v3 0/2] use unique out file in t5411 Jiang Xin
2021-02-11 21:52                                                           ` Junio C Hamano
2021-02-13 15:13                                                             ` Jiang Xin
2021-01-21  2:53                                                         ` [PATCH v3 1/2] t5411: use different out file to prevent overwriting Jiang Xin
2021-01-21  2:53                                                         ` [PATCH v3 2/2] t5411: refactor check of refs using test_cmp_refs Jiang Xin
2021-01-19 10:24                                                     ` [PATCH v2 " Jiang Xin
2021-01-18 13:30                                                 ` [PATCH " Jiang Xin
2020-08-27 15:45                                             ` [PATCH v19 04/10] receive-pack: feed report options to post-receive Jiang Xin
2020-08-27 15:45                                             ` [PATCH v19 05/10] New capability "report-status-v2" for git-push Jiang Xin
2020-08-27 15:45                                             ` [PATCH v19 06/10] doc: add document for capability report-status-v2 Jiang Xin
2020-08-27 15:45                                             ` [PATCH v19 07/10] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-08-27 15:45                                             ` [PATCH v19 08/10] t5411: test updates of remote-tracking branches Jiang Xin
2020-08-27 15:45                                             ` [PATCH v19 09/10] transport: parse report options for tracking refs Jiang Xin
2020-08-27 15:45                                             ` [PATCH v19 10/10] doc: add documentation for the proc-receive hook Jiang Xin
2020-08-24 17:41                                           ` [PATCH v18 01/10] transport: not report a non-head push as a branch Jiang Xin
2020-08-24 17:41                                           ` [PATCH v18 02/10] t5411: add basic test cases for proc-receive hook Jiang Xin
2020-08-24 17:41                                           ` [PATCH v18 03/10] receive-pack: add new " Jiang Xin
2020-08-24 17:41                                           ` [PATCH v18 04/10] receive-pack: feed report options to post-receive Jiang Xin
2020-08-24 17:41                                           ` [PATCH v18 05/10] New capability "report-status-v2" for git-push Jiang Xin
2020-08-24 17:41                                           ` [PATCH v18 06/10] doc: add document for capability report-status-v2 Jiang Xin
2020-08-24 17:41                                           ` [PATCH v18 07/10] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-08-24 17:42                                           ` [PATCH v18 08/10] t5411: test updates of remote-tracking branches Jiang Xin
2020-08-24 17:42                                           ` [PATCH v18 09/10] transport: parse report options for tracking refs Jiang Xin
2020-08-24 17:42                                           ` [PATCH v18 10/10] doc: add documentation for the proc-receive hook Jiang Xin
2020-08-15 17:17                                         ` [PATCH v17 01/10] transport: not report a non-head push as a branch Jiang Xin
2020-08-15 17:17                                         ` [PATCH v17 02/10] t5411: add basic test cases for proc-receive hook Jiang Xin
2020-08-15 17:17                                         ` [PATCH v17 03/10] receive-pack: add new " Jiang Xin
2020-08-17 20:53                                           ` Junio C Hamano
2020-08-15 17:17                                         ` [PATCH v17 04/10] New capability "report-status-v2" for git-push Jiang Xin
2020-08-17 21:12                                           ` Junio C Hamano
2020-08-15 17:17                                         ` [PATCH v17 05/10] doc: add document for capability report-status-v2 Jiang Xin
2020-08-15 17:17                                         ` [PATCH v17 06/10] receive-pack: feed report options to post-receive Jiang Xin
2020-08-17 21:15                                           ` Junio C Hamano
2020-08-15 17:17                                         ` [PATCH v17 07/10] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-08-17 21:25                                           ` Junio C Hamano
2020-08-15 17:17                                         ` [PATCH v17 08/10] t5411: test updates of remote-tracking branches Jiang Xin
2020-08-15 17:17                                         ` [PATCH v17 09/10] transport: parse report options for tracking refs Jiang Xin
2020-08-15 17:17                                         ` [PATCH v17 10/10] doc: add documentation for the proc-receive hook Jiang Xin
2020-05-18  9:40                                       ` [PATCH v16 01/11] transport: not report a non-head push as a branch Jiang Xin
2020-05-18  9:40                                       ` [PATCH v16 02/11] t5411: add basic test cases for proc-receive hook Jiang Xin
2020-05-18  9:40                                       ` [PATCH v16 03/11] receive-pack: add new " Jiang Xin
2020-05-18  9:40                                       ` [PATCH v16 04/11] New capability "report-status-v2" for git-push Jiang Xin
2020-05-18  9:40                                       ` [PATCH v16 05/11] doc: add document for capability report-status-v2 Jiang Xin
2020-05-18  9:40                                       ` [PATCH v16 06/11] receive-pack: feed report options to post-receive Jiang Xin
2020-05-18  9:40                                       ` [PATCH v16 07/11] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-05-18  9:40                                       ` [PATCH v16 08/11] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-05-18  9:40                                       ` [PATCH v16 09/11] t5411: test updates of remote-tracking branches Jiang Xin
2020-05-18  9:40                                       ` [PATCH v16 10/11] transport: parse report options for tracking refs Jiang Xin
2020-05-18  9:40                                       ` [PATCH v16 11/11] doc: add documentation for the proc-receive hook Jiang Xin
2020-05-07 16:10                                     ` [PATCH v15 1/7] transport: not report a non-head push as a branch Jiang Xin
2020-05-07 16:10                                     ` [PATCH v15 2/7] receive-pack: add new proc-receive hook Jiang Xin
2020-05-07 16:10                                     ` [PATCH v15 3/7] New capability "report-status-v2" for git-push Jiang Xin
2020-05-07 16:10                                     ` [PATCH v15 4/7] receive-pack: feed report options to post-receive Jiang Xin
2020-05-07 16:10                                     ` [PATCH v15 5/7] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-05-07 16:10                                     ` [PATCH v15 6/7] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-05-07 16:10                                     ` [PATCH v15 7/7] doc: add documentation for the proc-receive hook Jiang Xin
2020-05-05 14:41                                 ` [PATCH v14 1/7] transport: not report a non-head push as a branch Jiang Xin
2020-05-05 14:41                                 ` [PATCH v14 2/7] receive-pack: add new proc-receive hook Jiang Xin
2020-05-05 14:41                                 ` [PATCH v14 3/7] New capability "report-status-v2" for git-push Jiang Xin
2020-05-05 15:25                                   ` [PATCH v14 8/7] fixup! " Jiang Xin
2020-05-05 14:41                                 ` [PATCH v14 4/7] receive-pack: feed report options to post-receive Jiang Xin
2020-05-05 14:41                                 ` [PATCH v14 5/7] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-05-05 14:41                                 ` [PATCH v14 6/7] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-05-05 14:41                                 ` [PATCH v14 7/7] doc: add documentation for the proc-receive hook Jiang Xin
2020-05-07 17:27                                 ` [PATCH v12 3/7] receive-pack: add new " Jeff King
2020-04-14 12:32                   ` [PATCH v12 4/7] send-pack: extension for client-side status report Jiang Xin
2020-04-15 20:36                     ` Junio C Hamano
2020-04-14 12:32                   ` [PATCH v12 5/7] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-04-14 12:32                   ` [PATCH v12 6/7] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-04-14 12:32                   ` [PATCH v12 7/7] doc: add documentation for the proc-receive hook Jiang Xin
2020-04-12 13:30           ` [PATCH v10 3/8] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-04-12 21:38             ` Junio C Hamano
2020-04-13 11:16               ` Jiang Xin
2020-04-12 13:30           ` [PATCH v10 4/8] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-04-12 21:46             ` Junio C Hamano
2020-04-13 11:16               ` Jiang Xin
2020-04-12 13:30           ` [PATCH v10 5/8] connect: export parse_feature_value() Jiang Xin
2020-04-12 13:30           ` [PATCH v10 6/8] receive-pack: extension for server-side report Jiang Xin
2020-04-12 13:30           ` [PATCH v10 7/8] send-pack: extension for client-side status report Jiang Xin
2020-04-12 13:30           ` [PATCH v10 8/8] doc: add documentation for the proc-receive hook Jiang Xin
2020-04-07 12:08         ` [PATCH v9 1/6] transport: not report a non-head push as a branch Jiang Xin
2020-04-07 12:08         ` [PATCH v9 2/6] receive-pack: add new proc-receive hook Jiang Xin
2020-04-07 12:08         ` [PATCH v9 3/6] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-04-07 12:08         ` [PATCH v9 4/6] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-04-07 12:08         ` [PATCH v9 5/6] receive-pack: refactor report for proc-receive Jiang Xin
2020-04-07 12:08         ` [PATCH v9 6/6] doc: add documentation for the proc-receive hook Jiang Xin
2020-04-04 13:43       ` [PATCH v8 1/7] transport: not report a non-head push as a branch Jiang Xin
2020-04-04 13:43       ` [PATCH v8 2/7] receive-pack: add new proc-receive hook Jiang Xin
2020-04-04 13:43       ` [PATCH v8 3/7] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-04-04 13:43       ` [PATCH v8 4/7] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-04-04 13:43       ` [PATCH v8 5/7] receive-pack: refactor report for proc-receive Jiang Xin
2020-04-04 13:43       ` [PATCH v8 6/7] t5412: test the proc-receive hook on HTTP protocol Jiang Xin
2020-04-04 13:43       ` [PATCH v8 7/7] doc: add documentation for the proc-receive hook Jiang Xin
2020-04-03 16:08     ` [PATCH v7 1/7] transport: not report a non-head push as a branch Jiang Xin
2020-04-03 16:08     ` [PATCH v7 2/7] receive-pack: add new proc-receive hook Jiang Xin
2020-04-03 16:08     ` [PATCH v7 3/7] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-04-03 16:08     ` [PATCH v7 4/7] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-04-03 16:08     ` [PATCH v7 5/7] receive-pack: refactor report for proc-receive Jiang Xin
2020-04-03 16:08     ` [PATCH v7 6/7] t5412: test proc-receive hook on HTTP protocol Jiang Xin
2020-04-03 16:08     ` [PATCH v7 7/7] doc: add documentation for the proc-receive hook Jiang Xin
2020-04-02 16:35 ` [PATCH v6 1/7] transport: not report a non-head push as a branch Jiang Xin
2020-04-02 16:35 ` [PATCH v6 2/7] receive-pack: add new proc-receive hook Jiang Xin
2020-04-02 16:35 ` [PATCH v6 3/7] refs.c: refactor to reuse ref_is_hidden() Jiang Xin
2020-04-02 16:35 ` [PATCH v6 4/7] receive-pack: new config receive.procReceiveRefs Jiang Xin
2020-04-02 16:35 ` [PATCH v6 5/7] receive-pack: refactor report for proc-receive Jiang Xin
2020-04-02 16:35 ` [PATCH v6 6/7] t5412: test proc-receive hook on HTTP protocol Jiang Xin
2020-04-02 16:35 ` [PATCH v6 7/7] doc: add documentation for the proc-receive hook Jiang Xin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200418160334.15631-1-worldhello.net@gmail.com \
    --to=worldhello.net@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=zhiyou.jx@alibaba-inc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).