receive-pack: use default version 0 for proc-receive

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>

Jiang Xin committed Nov 11, 2020 at 19:32 UTC 80ffeb94f4c9eae4e099fec47e39105fc1e19132
4 files changed +138 -7
builtin/receive-pack.c
+6 -1
@@ -1192,7 +1192,12 @@ static int run_proc_receive_hook(struct command *commands,
1192 goto cleanup;
1193 }
1194
1195 - if (version != 1) {
1195 + switch (version) {
1196 + case 0:
1197 + /* fallthrough */
1198 + case 1:
1199 + break;
1200 + default:
1201 strbuf_addf(&errmsg, "proc-receive version '%d' is not supported",
1202 version);
1203 code = -1;
t/helper/test-proc-receive.c
+10 -6
@@ -45,8 +45,14 @@ static void proc_receive_verison(struct packet_reader *reader) {
45 if (packet_reader_read(reader) != PACKET_READ_NORMAL)
46 break;
47
48 + /* Ignore version negotiation for version 0 */
49 + if (version == 0)
50 + continue;
51 +
52 if (reader->pktlen > 8 && starts_with(reader->line, "version=")) {
53 server_version = atoi(reader->line+8);
54 + if (server_version != 1)
55 + die("bad protocol version: %d", server_version);
56 linelen = strlen(reader->line);
57 if (linelen < reader->pktlen) {
58 const char *feature_list = reader->line + linelen + 1;
@@ -58,15 +64,13 @@ static void proc_receive_verison(struct packet_reader *reader) {
64 }
65 }
66
61 - if (server_version != 1)
62 - die("bad protocol version: %d", server_version);
63 -
67 if (die_write_version)
68 die("die with the --die-write-version option");
69
67 - packet_write_fmt(1, "version=%d%c%s\n",
68 - version, '\0',
69 - use_push_options && !no_push_options ? "push-options": "");
70 + if (version != 0)
71 + packet_write_fmt(1, "version=%d%c%s\n",
72 + version, '\0',
73 + use_push_options && !no_push_options ? "push-options": "");
74 packet_flush(1);
75 }
76
t/t5411/test-0026-push-options.sh
+60
@@ -32,6 +32,66 @@ test_expect_success "enable push options ($PROTOCOL)" '
32 git -C "$upstream" config receive.advertisePushOptions true
33 '
34
35 +test_expect_success "setup version=0 for proc-receive hook ($PROTOCOL)" '
36 + write_script "$upstream/hooks/proc-receive" <<-EOF
37 + printf >&2 "# proc-receive hook\n"
38 + test-tool proc-receive -v \
39 + --version 0 \
40 + -r "ok refs/for/main/topic"
41 + EOF
42 +'
43 +
44 +# Refs of upstream : main(A)
45 +# Refs of workbench: main(A) tags/v123
46 +# git push -o ... : next(A) refs/for/main/topic
47 +test_expect_success "proc-receive: ignore push-options for version 0 ($PROTOCOL)" '
48 + git -C workbench push \
49 + --atomic \
50 + -o issue=123 \
51 + -o reviewer=user1 \
52 + origin \
53 + HEAD:refs/heads/next \
54 + HEAD:refs/for/main/topic \
55 + >out 2>&1 &&
56 + make_user_friendly_and_stable_output <out >actual &&
57 + cat >expect <<-EOF &&
58 + remote: # pre-receive hook
59 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
60 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/main/topic
61 + remote: # proc-receive hook
62 + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/main/topic
63 + remote: proc-receive> ok refs/for/main/topic
64 + remote: # post-receive hook
65 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
66 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/main/topic
67 + To <URL/of/upstream.git>
68 + * [new branch] HEAD -> next
69 + * [new reference] HEAD -> refs/for/main/topic
70 + EOF
71 + test_cmp expect actual &&
72 + git -C "$upstream" show-ref >out &&
73 + make_user_friendly_and_stable_output <out >actual &&
74 + cat >expect <<-EOF &&
75 + <COMMIT-A> refs/heads/main
76 + <COMMIT-A> refs/heads/next
77 + EOF
78 + test_cmp expect actual
79 +'
80 +
81 +test_expect_success "restore proc-receive hook ($PROTOCOL)" '
82 + write_script "$upstream/hooks/proc-receive" <<-EOF
83 + printf >&2 "# proc-receive hook\n"
84 + test-tool proc-receive -v \
85 + -r "ok refs/for/main/topic"
86 + EOF
87 +'
88 +
89 +# Refs of upstream : main(A) next(A)
90 +# Refs of workbench: main(A) tags/v123
91 +test_expect_success "cleanup ($PROTOCOL)" '
92 + git -C "$upstream" update-ref -d refs/heads/next
93 +'
94 +
95 # Refs of upstream : main(A)
96 # Refs of workbench: main(A) tags/v123
97 # git push -o ... : next(A) refs/for/main/topic
t/t5411/test-0027-push-options--porcelain.sh
+62
@@ -33,6 +33,68 @@ test_expect_success "enable push options ($PROTOCOL/porcelain)" '
33 git -C "$upstream" config receive.advertisePushOptions true
34 '
35
36 +test_expect_success "setup version=0 for proc-receive hook ($PROTOCOL/porcelain)" '
37 + write_script "$upstream/hooks/proc-receive" <<-EOF
38 + printf >&2 "# proc-receive hook\n"
39 + test-tool proc-receive -v \
40 + --version 0 \
41 + -r "ok refs/for/main/topic"
42 + EOF
43 +'
44 +
45 +# Refs of upstream : main(A)
46 +# Refs of workbench: main(A) tags/v123
47 +# git push -o ... : next(A) refs/for/main/topic
48 +test_expect_success "proc-receive: ignore push-options for version 0 ($PROTOCOL/porcelain)" '
49 + git -C workbench push \
50 + --porcelain \
51 + --atomic \
52 + -o issue=123 \
53 + -o reviewer=user1 \
54 + origin \
55 + HEAD:refs/heads/next \
56 + HEAD:refs/for/main/topic \
57 + >out 2>&1 &&
58 + make_user_friendly_and_stable_output <out >actual &&
59 + cat >expect <<-EOF &&
60 + remote: # pre-receive hook
61 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
62 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/main/topic
63 + remote: # proc-receive hook
64 + remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/main/topic
65 + remote: proc-receive> ok refs/for/main/topic
66 + remote: # post-receive hook
67 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
68 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/main/topic
69 + To <URL/of/upstream.git>
70 + * HEAD:refs/heads/next [new branch]
71 + * HEAD:refs/for/main/topic [new reference]
72 + Done
73 + EOF
74 + test_cmp expect actual &&
75 + git -C "$upstream" show-ref >out &&
76 + make_user_friendly_and_stable_output <out >actual &&
77 + cat >expect <<-EOF &&
78 + <COMMIT-A> refs/heads/main
79 + <COMMIT-A> refs/heads/next
80 + EOF
81 + test_cmp expect actual
82 +'
83 +
84 +test_expect_success "restore proc-receive hook ($PROTOCOL/porcelain)" '
85 + write_script "$upstream/hooks/proc-receive" <<-EOF
86 + printf >&2 "# proc-receive hook\n"
87 + test-tool proc-receive -v \
88 + -r "ok refs/for/main/topic"
89 + EOF
90 +'
91 +
92 +# Refs of upstream : main(A) next(A)
93 +# Refs of workbench: main(A) tags/v123
94 +test_expect_success "cleanup ($PROTOCOL/porcelain)" '
95 + git -C "$upstream" update-ref -d refs/heads/next
96 +'
97 +
98 # Refs of upstream : main(A)
99 # Refs of workbench: main(A) tags/v123
100 # git push -o ... : next(A) refs/for/main/topic