From: Jiang Xin <zhiyou.jx@xxxxxxxxxxxxxxx> 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 --