]> git.ipfire.org Git - thirdparty/git.git/commitdiff
receive-pack: use default version 0 for proc-receive
authorJiang Xin <worldhello.net@gmail.com>
Wed, 11 Nov 2020 11:32:02 +0000 (19:32 +0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 11 Nov 2020 20:46:56 +0000 (12:46 -0800)
In the verison negotiation phase between "receive-pack" and
"proc-receive", "proc-receive" can send an empty flush-pkt to end the
negotiation and use default version 0. Capabilities (such as
"push-options") are not supported in version 0.

Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/receive-pack.c
t/helper/test-proc-receive.c
t/t5411/test-0026-push-options.sh
t/t5411/test-0027-push-options--porcelain.sh

index 2bd736525f82cbf36187a263c6ea834a3cf915b1..f1f0f7bef670d0867c610789c23fd7176e4770b0 100644 (file)
@@ -1192,7 +1192,12 @@ static int run_proc_receive_hook(struct command *commands,
                goto cleanup;
        }
 
-       if (version != 1) {
+       switch (version) {
+       case 0:
+               /* fallthrough */
+       case 1:
+               break;
+       default:
                strbuf_addf(&errmsg, "proc-receive version '%d' is not supported",
                            version);
                code = -1;
index 6652cedcee693a294a2dad85cf7b342860e6fdf3..cc08506cf0bb73b1aefda41079f60cba1edcb9c1 100644 (file)
@@ -45,8 +45,14 @@ static void proc_receive_verison(struct packet_reader *reader) {
                if (packet_reader_read(reader) != PACKET_READ_NORMAL)
                        break;
 
+               /* Ignore version negotiation for version 0 */
+               if (version == 0)
+                       continue;
+
                if (reader->pktlen > 8 && starts_with(reader->line, "version=")) {
                        server_version = atoi(reader->line+8);
+                       if (server_version != 1)
+                               die("bad protocol version: %d", server_version);
                        linelen = strlen(reader->line);
                        if (linelen < reader->pktlen) {
                                const char *feature_list = reader->line + linelen + 1;
@@ -58,15 +64,13 @@ static void proc_receive_verison(struct packet_reader *reader) {
                }
        }
 
-       if (server_version != 1)
-               die("bad protocol version: %d", server_version);
-
        if (die_write_version)
                die("die with the --die-write-version option");
 
-       packet_write_fmt(1, "version=%d%c%s\n",
-                        version, '\0',
-                        use_push_options && !no_push_options ? "push-options": "");
+       if (version != 0)
+               packet_write_fmt(1, "version=%d%c%s\n",
+                                version, '\0',
+                                use_push_options && !no_push_options ? "push-options": "");
        packet_flush(1);
 }
 
index d414be87d0b7b8208fc8c1e004f547c664e0ff8b..e88edb16a445c88f008f2b82aab8c61e4ff47d55 100644 (file)
@@ -32,6 +32,66 @@ test_expect_success "enable push options ($PROTOCOL)" '
        git -C "$upstream" config receive.advertisePushOptions true
 '
 
+test_expect_success "setup version=0 for proc-receive hook ($PROTOCOL)" '
+       write_script "$upstream/hooks/proc-receive" <<-EOF
+       printf >&2 "# proc-receive hook\n"
+       test-tool proc-receive -v \
+               --version 0 \
+               -r "ok refs/for/main/topic"
+       EOF
+'
+
+# Refs of upstream : main(A)
+# Refs of workbench: main(A)  tags/v123
+# git push -o ...  :                       next(A)  refs/for/main/topic
+test_expect_success "proc-receive: ignore push-options for version 0 ($PROTOCOL)" '
+       git -C workbench push \
+               --atomic \
+               -o issue=123 \
+               -o reviewer=user1 \
+               origin \
+               HEAD:refs/heads/next \
+               HEAD:refs/for/main/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/main/topic
+       remote: # proc-receive hook
+       remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/main/topic
+       remote: proc-receive> ok refs/for/main/topic
+       remote: # post-receive hook
+       remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
+       remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/main/topic
+       To <URL/of/upstream.git>
+        * [new branch] HEAD -> next
+        * [new reference] HEAD -> refs/for/main/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/main
+       <COMMIT-A> refs/heads/next
+       EOF
+       test_cmp expect actual
+'
+
+test_expect_success "restore 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/main/topic"
+       EOF
+'
+
+# Refs of upstream : main(A)             next(A)
+# Refs of workbench: main(A)  tags/v123
+test_expect_success "cleanup ($PROTOCOL)" '
+       git -C "$upstream" update-ref -d refs/heads/next
+'
+
 # Refs of upstream : main(A)
 # Refs of workbench: main(A)  tags/v123
 # git push -o ...  :                       next(A)  refs/for/main/topic
index d5d0dcb172fd83565efdf308811f0927d0948fb6..3a6561b5eab465b3b9eab20e29a3c4fa992d6a7c 100644 (file)
@@ -33,6 +33,68 @@ test_expect_success "enable push options ($PROTOCOL/porcelain)" '
        git -C "$upstream" config receive.advertisePushOptions true
 '
 
+test_expect_success "setup version=0 for proc-receive hook ($PROTOCOL/porcelain)" '
+       write_script "$upstream/hooks/proc-receive" <<-EOF
+       printf >&2 "# proc-receive hook\n"
+       test-tool proc-receive -v \
+               --version 0 \
+               -r "ok refs/for/main/topic"
+       EOF
+'
+
+# Refs of upstream : main(A)
+# Refs of workbench: main(A)  tags/v123
+# git push -o ...  :                       next(A)  refs/for/main/topic
+test_expect_success "proc-receive: ignore push-options for version 0 ($PROTOCOL/porcelain)" '
+       git -C workbench push \
+               --porcelain \
+               --atomic \
+               -o issue=123 \
+               -o reviewer=user1 \
+               origin \
+               HEAD:refs/heads/next \
+               HEAD:refs/for/main/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/main/topic
+       remote: # proc-receive hook
+       remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/main/topic
+       remote: proc-receive> ok refs/for/main/topic
+       remote: # post-receive hook
+       remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
+       remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/main/topic
+       To <URL/of/upstream.git>
+       *    HEAD:refs/heads/next    [new branch]
+       *    HEAD:refs/for/main/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/main
+       <COMMIT-A> refs/heads/next
+       EOF
+       test_cmp expect actual
+'
+
+test_expect_success "restore proc-receive hook ($PROTOCOL/porcelain)" '
+       write_script "$upstream/hooks/proc-receive" <<-EOF
+       printf >&2 "# proc-receive hook\n"
+       test-tool proc-receive -v \
+               -r "ok refs/for/main/topic"
+       EOF
+'
+
+# Refs of upstream : main(A)             next(A)
+# Refs of workbench: main(A)  tags/v123
+test_expect_success "cleanup ($PROTOCOL/porcelain)" '
+       git -C "$upstream" update-ref -d refs/heads/next
+'
+
 # Refs of upstream : main(A)
 # Refs of workbench: main(A)  tags/v123
 # git push -o ...  :                       next(A)  refs/for/main/topic