{"thread":{"id":"54305","subject":"[PATCH 01/26] transport: not report a non-head push as a branch","startedAt":"2020-09-25T22:19:52Z","lastAt":"2020-09-25T22:21:40Z","messageCount":4,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":26},"messages":[{"id":"406404","messageId":"20200925221944.4020954-1-gitster@pobox.com","threadId":"54305","inReplyTo":null,"subject":"[PATCH 01/26] transport: not report a non-head push as a branch","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-09-25T22:19:19Z","receivedAt":"2020-09-25T22:19:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"From: Jiang Xin <zhiyou.jx@alibaba-inc.com>\n\nWhen pushing a new reference (not a head or tag), report it as a new\nreference instead of a new branch.\n\nSigned-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/t5516-fetch-push.sh | 2 +-\n transport.c           | 9 ++++++---\n 2 files changed, 7 insertions(+), 4 deletions(-)\n\ndiff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh\nindex 9c6218f568..77938db77f 100755\n--- a/t/t5516-fetch-push.sh\n+++ b/t/t5516-fetch-push.sh\n@@ -1039,7 +1039,7 @@ test_force_fetch_tag \"annotated tag\" \"-f -a -m'tag message'\"\n test_expect_success 'push --porcelain' '\n \tmk_empty testrepo &&\n \techo >.git/foo  \"To testrepo\" &&\n-\techo >>.git/foo \"*\trefs/heads/master:refs/remotes/origin/master\t[new branch]\"  &&\n+\techo >>.git/foo \"*\trefs/heads/master:refs/remotes/origin/master\t[new reference]\"  &&\n \techo >>.git/foo \"Done\" &&\n \tgit push >.git/bar --porcelain  testrepo refs/heads/master:refs/remotes/origin/master &&\n \t(\ndiff --git a/transport.c b/transport.c\nindex 15f5ba4e8f..26fefd13c1 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -500,9 +500,12 @@ static void print_ok_ref_status(struct ref *ref, int porcelain, int summary_widt\n \t\t\t\t porcelain, summary_width);\n \telse if (is_null_oid(&ref->old_oid))\n \t\tprint_ref_status('*',\n-\t\t\t(starts_with(ref->name, \"refs/tags/\") ? \"[new tag]\" :\n-\t\t\t\"[new branch]\"),\n-\t\t\tref, ref->peer_ref, NULL, porcelain, summary_width);\n+\t\t\t\t (starts_with(ref->name, \"refs/tags/\")\n+\t\t\t\t  ? \"[new tag]\"\n+\t\t\t\t  : (starts_with(ref->name, \"refs/heads/\")\n+\t\t\t\t     ? \"[new branch]\"\n+\t\t\t\t     : \"[new reference]\")),\n+\t\t\t\t ref, ref->peer_ref, NULL, porcelain, summary_width);\n \telse {\n \t\tstruct strbuf quickref = STRBUF_INIT;\n \t\tchar type;\n-- \n2.28.0-733-g3cecc26178\n\n"},{"id":"406405","messageId":"20200925221944.4020954-2-gitster@pobox.com","threadId":"54305","inReplyTo":"20200925221944.4020954-1-gitster@pobox.com","subject":"[PATCH 02/26] t5411: add basic test cases for proc-receive hook","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-09-25T22:19:20Z","receivedAt":"2020-09-25T22:20:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"From: Jiang Xin <zhiyou.jx@alibaba-inc.com>\n\nTopic \"proc-receive-hook\" will change the workflow and output of\ngit-push. Add some basic test cases in t5411 before introducing the new\ntopic.\n\nSigned-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/t5411-proc-receive-hook.sh                  | 108 +++++++++++++\n t/t5411/common-functions.sh                   |  56 +++++++\n t/t5411/test-0000-standard-git-push.sh        | 143 +++++++++++++++++\n .../test-0001-standard-git-push--porcelain.sh | 147 ++++++++++++++++++\n t/t5411/test-0002-pre-receive-declined.sh     |  33 ++++\n ...st-0003-pre-receive-declined--porcelain.sh |  34 ++++\n 6 files changed, 521 insertions(+)\n create mode 100755 t/t5411-proc-receive-hook.sh\n create mode 100644 t/t5411/common-functions.sh\n create mode 100644 t/t5411/test-0000-standard-git-push.sh\n create mode 100644 t/t5411/test-0001-standard-git-push--porcelain.sh\n create mode 100644 t/t5411/test-0002-pre-receive-declined.sh\n create mode 100644 t/t5411/test-0003-pre-receive-declined--porcelain.sh\n\ndiff --git a/t/t5411-proc-receive-hook.sh b/t/t5411-proc-receive-hook.sh\nnew file mode 100755\nindex 0000000000..3a684353a8\n--- /dev/null\n+++ b/t/t5411-proc-receive-hook.sh\n@@ -0,0 +1,108 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2020 Jiang Xin\n+#\n+\n+test_description='Test proc-receive hook'\n+\n+. ./test-lib.sh\n+\n+. \"$TEST_DIRECTORY\"/t5411/common-functions.sh\n+\n+setup_upstream_and_workbench () {\n+\t# Refs of upstream : master(A)\n+\t# Refs of workbench: master(A)  tags/v123\n+\ttest_expect_success \"setup upstream and workbench\" '\n+\t\trm -rf upstream.git &&\n+\t\trm -rf workbench &&\n+\t\tgit init --bare upstream.git &&\n+\t\tgit init workbench &&\n+\t\tcreate_commits_in workbench A B &&\n+\t\t(\n+\t\t\tcd workbench &&\n+\t\t\t# Try to make a stable fixed width for abbreviated commit ID,\n+\t\t\t# this fixed-width oid will be replaced with \"<OID>\".\n+\t\t\tgit config core.abbrev 7 &&\n+\t\t\tgit tag -m \"v123\" v123 $A &&\n+\t\t\tgit remote add origin ../upstream.git &&\n+\t\t\tgit push origin master &&\n+\t\t\tgit update-ref refs/heads/master $A $B &&\n+\t\t\tgit -C ../upstream.git update-ref \\\n+\t\t\t\trefs/heads/master $A $B\n+\t\t) &&\n+\t\tTAG=$(git -C workbench rev-parse v123) &&\n+\n+\t\t# setup pre-receive hook\n+\t\twrite_script upstream.git/hooks/pre-receive <<-\\EOF &&\n+\t\texec >&2\n+\t\techo \"# pre-receive hook\"\n+\t\twhile read old new ref\n+\t\tdo\n+\t\t\techo \"pre-receive< $old $new $ref\"\n+\t\tdone\n+\t\tEOF\n+\n+\t\t# setup post-receive hook\n+\t\twrite_script upstream.git/hooks/post-receive <<-\\EOF &&\n+\t\texec >&2\n+\t\techo \"# post-receive hook\"\n+\t\twhile read old new ref\n+\t\tdo\n+\t\t\techo \"post-receive< $old $new $ref\"\n+\t\tdone\n+\t\tEOF\n+\n+\t\tupstream=upstream.git\n+\t'\n+}\n+\n+run_proc_receive_hook_test() {\n+\tcase $1 in\n+\thttp)\n+\t\tPROTOCOL=\"HTTP protocol\"\n+\t\tURL_PREFIX=\"http://.*\"\n+\t\t;;\n+\tlocal)\n+\t\tPROTOCOL=\"builtin protocol\"\n+\t\tURL_PREFIX=\"\\.\\.\"\n+\t\t;;\n+\tesac\n+\n+\t# Include test cases for both file and HTTP protocol\n+\tfor t in  \"$TEST_DIRECTORY\"/t5411/test-*.sh\n+\tdo\n+\t\t. \"$t\"\n+\tdone\n+}\n+\n+# Initialize the upstream repository and local workbench.\n+setup_upstream_and_workbench\n+\n+# Run test cases for 'proc-receive' hook on local file protocol.\n+run_proc_receive_hook_test local\n+\n+ROOT_PATH=\"$PWD\"\n+. \"$TEST_DIRECTORY\"/lib-gpg.sh\n+. \"$TEST_DIRECTORY\"/lib-httpd.sh\n+. \"$TEST_DIRECTORY\"/lib-terminal.sh\n+start_httpd\n+\n+# Re-initialize the upstream repository and local workbench.\n+setup_upstream_and_workbench\n+\n+# Refs of upstream : master(A)\n+# Refs of workbench: master(A)  tags/v123\n+test_expect_success \"setup for HTTP protocol\" '\n+\tgit -C upstream.git config http.receivepack true &&\n+\tupstream=\"$HTTPD_DOCUMENT_ROOT_PATH/upstream.git\" &&\n+\tmv upstream.git \"$upstream\" &&\n+\tgit -C workbench remote set-url origin \"$HTTPD_URL/auth-push/smart/upstream.git\" &&\n+\tset_askpass user@host pass@host\n+'\n+\n+setup_askpass_helper\n+\n+# Run test cases for 'proc-receive' hook on HTTP protocol.\n+run_proc_receive_hook_test http\n+\n+test_done\ndiff --git a/t/t5411/common-functions.sh b/t/t5411/common-functions.sh\nnew file mode 100644\nindex 0000000000..6580bebd8e\n--- /dev/null\n+++ b/t/t5411/common-functions.sh\n@@ -0,0 +1,56 @@\n+# Create commits in <repo> and assign each commit's oid to shell variables\n+# given in the arguments (A, B, and C). E.g.:\n+#\n+#     create_commits_in <repo> A B C\n+#\n+# NOTE: Never calling this function from a subshell since variable\n+# assignments will disappear when subshell exits.\n+create_commits_in () {\n+\trepo=\"$1\" &&\n+\tif ! parent=$(git -C \"$repo\" rev-parse HEAD^{} --)\n+\tthen\n+\t\tparent=\n+\tfi &&\n+\tT=$(git -C \"$repo\" write-tree) &&\n+\tshift &&\n+\twhile test $# -gt 0\n+\tdo\n+\t\tname=$1 &&\n+\t\ttest_tick &&\n+\t\tif test -z \"$parent\"\n+\t\tthen\n+\t\t\toid=$(echo $name | git -C \"$repo\" commit-tree $T)\n+\t\telse\n+\t\t\toid=$(echo $name | git -C \"$repo\" commit-tree -p $parent $T)\n+\t\tfi &&\n+\t\teval $name=$oid &&\n+\t\tparent=$oid &&\n+\t\tshift ||\n+\t\treturn 1\n+\tdone &&\n+\tgit -C \"$repo\" update-ref refs/heads/master $oid\n+}\n+\n+# Format the output of git-push, git-show-ref and other commands to make a\n+# user-friendly and stable text.  We can easily prepare the expect text\n+# without having to worry about future changes of the commit ID and spaces\n+# of the output.  Single quotes are replaced with double quotes, because\n+# it is boring to prepare unquoted single quotes in expect text.  We also\n+# remove some locale error messages, which break test if we turn on\n+# `GIT_TEST_GETTEXT_POISON=true` in order to test unintentional translations\n+# on plumbing commands.\n+make_user_friendly_and_stable_output () {\n+\tsed \\\n+\t\t-e \"s/  *\\$//\" \\\n+\t\t-e \"s/   */ /g\" \\\n+\t\t-e \"s/'/\\\"/g\" \\\n+\t\t-e \"s/\t/    /g\" \\\n+\t\t-e \"s/$A/<COMMIT-A>/g\" \\\n+\t\t-e \"s/$B/<COMMIT-B>/g\" \\\n+\t\t-e \"s/$TAG/<TAG-v123>/g\" \\\n+\t\t-e \"s/$ZERO_OID/<ZERO-OID>/g\" \\\n+\t\t-e \"s/$(echo $A | cut -c1-7)[0-9a-f]*/<OID-A>/g\" \\\n+\t\t-e \"s/$(echo $B | cut -c1-7)[0-9a-f]*/<OID-B>/g\" \\\n+\t\t-e \"s#To $URL_PREFIX/upstream.git#To <URL/of/upstream.git>#\" \\\n+\t\t-e \"/^error: / d\"\n+}\ndiff --git a/t/t5411/test-0000-standard-git-push.sh b/t/t5411/test-0000-standard-git-push.sh\nnew file mode 100644\nindex 0000000000..e206587348\n--- /dev/null\n+++ b/t/t5411/test-0000-standard-git-push.sh\n@@ -0,0 +1,143 @@\n+# Refs of upstream : master(A)  \n+# Refs of workbench: master(A)  tags/v123\n+# git-push         : master(B)             next(A)\n+test_expect_success \"git-push ($PROTOCOL)\" '\n+\tgit -C workbench push origin \\\n+\t\t$B:refs/heads/master \\\n+\t\tHEAD:refs/heads/next \\\n+\t\t>out 2>&1 &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\tremote: # pre-receive hook\n+\tremote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master\n+\tremote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next\n+\tremote: # post-receive hook\n+\tremote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master\n+\tremote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next\n+\tTo <URL/of/upstream.git>\n+\t <OID-A>..<OID-B> <COMMIT-B> -> master\n+\t * [new branch] HEAD -> next\n+\tEOF\n+\ttest_cmp expect actual &&\n+\tgit -C \"$upstream\" show-ref >out &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\t<COMMIT-B> refs/heads/master\n+\t<COMMIT-A> refs/heads/next\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+# Refs of upstream : master(B)  next(A)\n+# Refs of workbench: master(A)           tags/v123\n+# git-push --atomic: master(A)  next(B)\n+test_expect_success \"git-push --atomic ($PROTOCOL)\" '\n+\ttest_must_fail git -C workbench push --atomic origin \\\n+\t\tmaster \\\n+\t\t$B:refs/heads/next \\\n+\t\t>out 2>&1 &&\n+\tmake_user_friendly_and_stable_output <out |\n+\t\tsed -n \\\n+\t\t\t-e \"/^To / { s/   */ /g; p; }\" \\\n+\t\t\t-e \"/^ ! / { s/   */ /g; p; }\" \\\n+\t\t\t>actual &&\n+\tcat >expect <<-EOF &&\n+\tTo <URL/of/upstream.git>\n+\t ! [rejected] master -> master (non-fast-forward)\n+\t ! [rejected] <COMMIT-B> -> next (atomic push failed)\n+\tEOF\n+\ttest_cmp expect actual &&\n+\tgit -C \"$upstream\" show-ref >out &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\t<COMMIT-B> refs/heads/master\n+\t<COMMIT-A> refs/heads/next\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+# Refs of upstream : master(B)  next(A)\n+# Refs of workbench: master(A)           tags/v123\n+# git-push         : master(A)  next(B)\n+test_expect_success \"non-fast-forward git-push ($PROTOCOL)\" '\n+\ttest_must_fail git \\\n+\t\t-C workbench \\\n+\t\t-c advice.pushUpdateRejected=false \\\n+\t\tpush origin \\\n+\t\tmaster \\\n+\t\t$B:refs/heads/next \\\n+\t\t>out 2>&1 &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\tremote: # pre-receive hook\n+\tremote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/next\n+\tremote: # post-receive hook\n+\tremote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/next\n+\tTo <URL/of/upstream.git>\n+\t <OID-A>..<OID-B> <COMMIT-B> -> next\n+\t ! [rejected] master -> master (non-fast-forward)\n+\tEOF\n+\ttest_cmp expect actual &&\n+\tgit -C \"$upstream\" show-ref >out &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\t<COMMIT-B> refs/heads/master\n+\t<COMMIT-B> refs/heads/next\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+# Refs of upstream : master(B)  next(B)\n+# Refs of workbench: master(A)           tags/v123\n+# git-push -f      : master(A)  NULL     tags/v123  refs/review/master/topic(A)  a/b/c(A)\n+test_expect_success \"git-push -f ($PROTOCOL)\" '\n+\tgit -C workbench push -f origin \\\n+\t\trefs/tags/v123 \\\n+\t\t:refs/heads/next \\\n+\t\tmaster \\\n+\t\tmaster:refs/review/master/topic \\\n+\t\tHEAD:refs/heads/a/b/c \\\n+\t\t>out 2>&1 &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\tremote: # pre-receive hook\n+\tremote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master\n+\tremote: pre-receive< <COMMIT-B> <ZERO-OID> refs/heads/next\n+\tremote: pre-receive< <ZERO-OID> <TAG-v123> refs/tags/v123\n+\tremote: pre-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic\n+\tremote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c\n+\tremote: # post-receive hook\n+\tremote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master\n+\tremote: post-receive< <COMMIT-B> <ZERO-OID> refs/heads/next\n+\tremote: post-receive< <ZERO-OID> <TAG-v123> refs/tags/v123\n+\tremote: post-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic\n+\tremote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c\n+\tTo <URL/of/upstream.git>\n+\t + <OID-B>...<OID-A> master -> master (forced update)\n+\t - [deleted] next\n+\t * [new tag] v123 -> v123\n+\t * [new reference] master -> refs/review/master/topic\n+\t * [new branch] HEAD -> a/b/c\n+\tEOF\n+\ttest_cmp expect actual &&\n+\tgit -C \"$upstream\" show-ref >out &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\t<COMMIT-A> refs/heads/a/b/c\n+\t<COMMIT-A> refs/heads/master\n+\t<COMMIT-A> refs/review/master/topic\n+\t<TAG-v123> refs/tags/v123\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+# Refs of upstream : master(A)  tags/v123  refs/review/master/topic(A)  a/b/c(A)\n+# Refs of workbench: master(A)  tags/v123\n+test_expect_success \"cleanup ($PROTOCOL)\" '\n+\t(\n+\t\tcd \"$upstream\" &&\n+\t\tgit update-ref -d refs/review/master/topic &&\n+\t\tgit update-ref -d refs/tags/v123 &&\n+\t\tgit update-ref -d refs/heads/a/b/c\n+\t)\n+'\ndiff --git a/t/t5411/test-0001-standard-git-push--porcelain.sh b/t/t5411/test-0001-standard-git-push--porcelain.sh\nnew file mode 100644\nindex 0000000000..48f6fcc846\n--- /dev/null\n+++ b/t/t5411/test-0001-standard-git-push--porcelain.sh\n@@ -0,0 +1,147 @@\n+# Refs of upstream : master(A)  \n+# Refs of workbench: master(A)  tags/v123\n+# git-push         : master(B)             next(A)\n+test_expect_success \"git-push ($PROTOCOL/porcelain)\" '\n+\tgit -C workbench push --porcelain origin \\\n+\t\t$B:refs/heads/master \\\n+\t\tHEAD:refs/heads/next \\\n+\t\t>out 2>&1 &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\tremote: # pre-receive hook\n+\tremote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master\n+\tremote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next\n+\tremote: # post-receive hook\n+\tremote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master\n+\tremote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next\n+\tTo <URL/of/upstream.git>\n+\t     <COMMIT-B>:refs/heads/master    <OID-A>..<OID-B>\n+\t*    HEAD:refs/heads/next    [new branch]\n+\tDone\n+\tEOF\n+\ttest_cmp expect actual &&\n+\tgit -C \"$upstream\" show-ref >out &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\t<COMMIT-B> refs/heads/master\n+\t<COMMIT-A> refs/heads/next\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+# Refs of upstream : master(B)  next(A)\n+# Refs of workbench: master(A)           tags/v123\n+# git-push --atomic: master(A)  next(B)\n+test_expect_success \"git-push --atomic ($PROTOCOL/porcelain)\" '\n+\ttest_must_fail git -C workbench push --atomic --porcelain origin \\\n+\t\tmaster \\\n+\t\t$B:refs/heads/next \\\n+\t\t>out 2>&1 &&\n+\tmake_user_friendly_and_stable_output <out |\n+\t\tsed -n \\\n+\t\t\t-e \"s/^# GETTEXT POISON #//\" \\\n+\t\t\t-e \"/^To / { s/   */ /g; p; }\" \\\n+\t\t\t-e \"/^! / { s/   */ /g; p; }\" \\\n+\t\t\t>actual &&\n+\tcat >expect <<-EOF &&\n+\tTo <URL/of/upstream.git>\n+\t! refs/heads/master:refs/heads/master [rejected] (non-fast-forward)\n+\t! <COMMIT-B>:refs/heads/next [rejected] (atomic push failed)\n+\tEOF\n+\ttest_cmp expect actual &&\n+\tgit -C \"$upstream\" show-ref >out &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\t<COMMIT-B> refs/heads/master\n+\t<COMMIT-A> refs/heads/next\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+# Refs of upstream : master(B)  next(A)\n+# Refs of workbench: master(A)           tags/v123\n+# git-push         : master(A)  next(B)\n+test_expect_success \"non-fast-forward git-push ($PROTOCOL/porcelain)\" '\n+\ttest_must_fail git \\\n+\t\t-C workbench \\\n+\t\t-c advice.pushUpdateRejected=false \\\n+\t\tpush --porcelain origin \\\n+\t\tmaster \\\n+\t\t$B:refs/heads/next \\\n+\t\t>out 2>&1 &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\tremote: # pre-receive hook\n+\tremote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/next\n+\tremote: # post-receive hook\n+\tremote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/next\n+\tTo <URL/of/upstream.git>\n+\t     <COMMIT-B>:refs/heads/next    <OID-A>..<OID-B>\n+\t!    refs/heads/master:refs/heads/master    [rejected] (non-fast-forward)\n+\tDone\n+\tEOF\n+\ttest_cmp expect actual &&\n+\tgit -C \"$upstream\" show-ref >out &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\t<COMMIT-B> refs/heads/master\n+\t<COMMIT-B> refs/heads/next\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+# Refs of upstream : master(B)  next(B)\n+# Refs of workbench: master(A)           tags/v123\n+# git-push -f      : master(A)  NULL     tags/v123  refs/review/master/topic(A)  a/b/c(A)\n+test_expect_success \"git-push -f ($PROTOCOL/porcelain)\" '\n+\tgit -C workbench push --porcelain -f origin \\\n+\t\trefs/tags/v123 \\\n+\t\t:refs/heads/next \\\n+\t\tmaster \\\n+\t\tmaster:refs/review/master/topic \\\n+\t\tHEAD:refs/heads/a/b/c \\\n+\t\t>out 2>&1 &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\tremote: # pre-receive hook\n+\tremote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master\n+\tremote: pre-receive< <COMMIT-B> <ZERO-OID> refs/heads/next\n+\tremote: pre-receive< <ZERO-OID> <TAG-v123> refs/tags/v123\n+\tremote: pre-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic\n+\tremote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c\n+\tremote: # post-receive hook\n+\tremote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master\n+\tremote: post-receive< <COMMIT-B> <ZERO-OID> refs/heads/next\n+\tremote: post-receive< <ZERO-OID> <TAG-v123> refs/tags/v123\n+\tremote: post-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic\n+\tremote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c\n+\tTo <URL/of/upstream.git>\n+\t+    refs/heads/master:refs/heads/master    <OID-B>...<OID-A> (forced update)\n+\t-    :refs/heads/next    [deleted]\n+\t*    refs/tags/v123:refs/tags/v123    [new tag]\n+\t*    refs/heads/master:refs/review/master/topic    [new reference]\n+\t*    HEAD:refs/heads/a/b/c    [new branch]\n+\tDone\n+\tEOF\n+\ttest_cmp expect actual &&\n+\tgit -C \"$upstream\" show-ref >out &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\t<COMMIT-A> refs/heads/a/b/c\n+\t<COMMIT-A> refs/heads/master\n+\t<COMMIT-A> refs/review/master/topic\n+\t<TAG-v123> refs/tags/v123\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+# Refs of upstream : master(A)  tags/v123  refs/review/master/topic(A)  a/b/c(A)\n+# Refs of workbench: master(A)  tags/v123\n+test_expect_success \"cleanup ($PROTOCOL/porcelain)\" '\n+\t(\n+\t\tcd \"$upstream\" &&\n+\t\tgit update-ref -d refs/review/master/topic &&\n+\t\tgit update-ref -d refs/tags/v123 &&\n+\t\tgit update-ref -d refs/heads/a/b/c\n+\t)\n+'\ndiff --git a/t/t5411/test-0002-pre-receive-declined.sh b/t/t5411/test-0002-pre-receive-declined.sh\nnew file mode 100644\nindex 0000000000..c246f7e68e\n--- /dev/null\n+++ b/t/t5411/test-0002-pre-receive-declined.sh\n@@ -0,0 +1,33 @@\n+test_expect_success \"setup pre-receive hook ($PROTOCOL)\" '\n+\tmv \"$upstream/hooks/pre-receive\" \"$upstream/hooks/pre-receive.ok\" &&\n+\twrite_script \"$upstream/hooks/pre-receive\" <<-EOF\n+\texit 1\n+\tEOF\n+'\n+\n+# Refs of upstream : master(A)\n+# Refs of workbench: master(A)  tags/v123\n+# git-push         : master(B)             next(A)\n+test_expect_success \"git-push is declined ($PROTOCOL)\" '\n+\ttest_must_fail git -C workbench push origin \\\n+\t\t$B:refs/heads/master \\\n+\t\tHEAD:refs/heads/next \\\n+\t\t>out 2>&1 &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\tTo <URL/of/upstream.git>\n+\t ! [remote rejected] <COMMIT-B> -> master (pre-receive hook declined)\n+\t ! [remote rejected] HEAD -> next (pre-receive hook declined)\n+\tEOF\n+\ttest_cmp expect actual &&\n+\tgit -C \"$upstream\" show-ref >out &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\t<COMMIT-A> refs/heads/master\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success \"cleanup ($PROTOCOL)\" '\n+\tmv \"$upstream/hooks/pre-receive.ok\" \"$upstream/hooks/pre-receive\"\n+'\ndiff --git a/t/t5411/test-0003-pre-receive-declined--porcelain.sh b/t/t5411/test-0003-pre-receive-declined--porcelain.sh\nnew file mode 100644\nindex 0000000000..b14894de81\n--- /dev/null\n+++ b/t/t5411/test-0003-pre-receive-declined--porcelain.sh\n@@ -0,0 +1,34 @@\n+test_expect_success \"setup pre-receive hook ($PROTOCOL/porcelain)\" '\n+\tmv \"$upstream/hooks/pre-receive\" \"$upstream/hooks/pre-receive.ok\" &&\n+\twrite_script \"$upstream/hooks/pre-receive\" <<-EOF\n+\texit 1\n+\tEOF\n+'\n+\n+# Refs of upstream : master(A)\n+# Refs of workbench: master(A)  tags/v123\n+# git-push         : master(B)             next(A)\n+test_expect_success \"git-push is declined ($PROTOCOL/porcelain)\" '\n+\ttest_must_fail git -C workbench push --porcelain origin \\\n+\t\t$B:refs/heads/master \\\n+\t\tHEAD:refs/heads/next \\\n+\t\t>out 2>&1 &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\tTo <URL/of/upstream.git>\n+\t!    <COMMIT-B>:refs/heads/master    [remote rejected] (pre-receive hook declined)\n+\t!    HEAD:refs/heads/next    [remote rejected] (pre-receive hook declined)\n+\tDone\n+\tEOF\n+\ttest_cmp expect actual &&\n+\tgit -C \"$upstream\" show-ref >out &&\n+\tmake_user_friendly_and_stable_output <out >actual &&\n+\tcat >expect <<-EOF &&\n+\t<COMMIT-A> refs/heads/master\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success \"cleanup ($PROTOCOL/porcelain)\" '\n+\tmv \"$upstream/hooks/pre-receive.ok\" \"$upstream/hooks/pre-receive\"\n+'\n-- \n2.28.0-733-g3cecc26178\n\n"},{"id":"406406","messageId":"xmqqd029jy5g.fsf@gitster.c.googlers.com","threadId":"54305","inReplyTo":"20200925221944.4020954-1-gitster@pobox.com","subject":"Re: [PATCH 01/26] transport: not report a non-head push as a branch","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-09-25T22:21:15Z","receivedAt":"2020-09-25T22:21:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> From: Jiang Xin <zhiyou.jx@alibaba-inc.com>\n>\n> When pushing a new reference (not a head or tag), report it as a new\n> reference instead of a new branch.\n\nSorry, operator error.  Please disregard.\n"},{"id":"406407","messageId":"xmqq8scxjy4x.fsf@gitster.c.googlers.com","threadId":"54305","inReplyTo":"20200925221944.4020954-2-gitster@pobox.com","subject":"Re: [PATCH 02/26] t5411: add basic test cases for proc-receive hook","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-09-25T22:21:34Z","receivedAt":"2020-09-25T22:21:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> From: Jiang Xin <zhiyou.jx@alibaba-inc.com>\n\nDitto.  An operator error.  Please disregard.\n"}]}