Merge branch 'jx/proc-receive-hook' into pu
"git receive-pack" that accepts requests by "git push" learned to outsource most of the ref updates to the new "proc-receive" hook. * jx/proc-receive-hook: doc: add documentation for the proc-receive hook transport: parse report options for tracking refs t5411: test updates of remote-tracking branches receive-pack: new config receive.procReceiveRefs refs.c: refactor to reuse ref_is_hidden() receive-pack: feed report options to post-receive doc: add document for capability report-status-v2 New capability "report-status-v2" for git-push receive-pack: add new proc-receive hook t5411: add basic test cases for proc-receive hook transport: not report a non-head push as a branch
This commit is contained in:
@ -114,6 +114,20 @@ receive.hideRefs::
|
|||||||
An attempt to update or delete a hidden ref by `git push` is
|
An attempt to update or delete a hidden ref by `git push` is
|
||||||
rejected.
|
rejected.
|
||||||
|
|
||||||
|
receive.procReceiveRefs::
|
||||||
|
This is a multi-valued variable that defines reference prefixes
|
||||||
|
to match the commands in `receive-pack`. Commands matching the
|
||||||
|
prefixes will be executed by an external hook "proc-receive",
|
||||||
|
instead of the internal `execute_commands` function. If this
|
||||||
|
variable is not defined, the "proc-receive" hook will never be
|
||||||
|
used, and all commands will be executed by the internal
|
||||||
|
`execute_commands` function.
|
||||||
|
|
||||||
|
For example, if this variable is set to "refs/for", pushing to
|
||||||
|
reference such as "refs/for/master" will not create or update a
|
||||||
|
reference named "refs/for/master", but may create or update a
|
||||||
|
pull request directly by running the hook "proc-receive".
|
||||||
|
|
||||||
receive.updateServerInfo::
|
receive.updateServerInfo::
|
||||||
If set to true, git-receive-pack will run git-update-server-info
|
If set to true, git-receive-pack will run git-update-server-info
|
||||||
after receiving data from git-push and updating refs.
|
after receiving data from git-push and updating refs.
|
||||||
|
@ -333,6 +333,68 @@ The default 'update' hook, when enabled--and with
|
|||||||
`hooks.allowunannotated` config option unset or set to false--prevents
|
`hooks.allowunannotated` config option unset or set to false--prevents
|
||||||
unannotated tags to be pushed.
|
unannotated tags to be pushed.
|
||||||
|
|
||||||
|
[[proc-receive]]
|
||||||
|
proc-receive
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This hook is invoked by linkgit:git-receive-pack[1]. If the server has
|
||||||
|
set the multi-valued config variable `receive.procReceiveRefs`, and the
|
||||||
|
commands sent to 'receive-pack' have matching reference names, these
|
||||||
|
commands will be executed by this hook, instead of by the internal
|
||||||
|
`execute_commands()` function. This hook is responsible for updating
|
||||||
|
the relevant references and reporting the results back to 'receive-pack'.
|
||||||
|
|
||||||
|
This hook executes once for the receive operation. It takes no
|
||||||
|
arguments, but uses a pkt-line format protocol to communicate with
|
||||||
|
'receive-pack' to read commands, push-options and send results. In the
|
||||||
|
following example for the protocol, the letter 'S' stands for
|
||||||
|
'receive-pack' and the letter 'H' stands for this hook.
|
||||||
|
|
||||||
|
# Version and features negotiation.
|
||||||
|
S: PKT-LINE(version=1\0push-options atomic...)
|
||||||
|
S: flush-pkt
|
||||||
|
H: PKT-LINE(version=1\0push-options...)
|
||||||
|
H: flush-pkt
|
||||||
|
|
||||||
|
# Send commands from server to the hook.
|
||||||
|
S: PKT-LINE(<old-oid> <new-oid> <ref>)
|
||||||
|
S: ... ...
|
||||||
|
S: flush-pkt
|
||||||
|
# Send push-options only if the 'push-options' feature is enabled.
|
||||||
|
S: PKT-LINE(push-option)
|
||||||
|
S: ... ...
|
||||||
|
S: flush-pkt
|
||||||
|
|
||||||
|
# Receive result from the hook.
|
||||||
|
# OK, run this command successfully.
|
||||||
|
H: PKT-LINE(ok <ref>)
|
||||||
|
# NO, I reject it.
|
||||||
|
H: PKT-LINE(ng <ref> <reason>)
|
||||||
|
# Fall through, let 'receive-pack' to execute it.
|
||||||
|
H: PKT-LINE(ok <ref>)
|
||||||
|
H: PKT-LINE(option fall-through)
|
||||||
|
# OK, but has an alternate reference. The alternate reference name
|
||||||
|
# and other status can be given in options
|
||||||
|
H: PKT-LINE(ok <ref>)
|
||||||
|
H: PKT-LINE(option refname <refname>)
|
||||||
|
H: PKT-LINE(option old-oid <old-oid>)
|
||||||
|
H: PKT-LINE(option new-oid <new-oid>)
|
||||||
|
H: PKT-LINE(option forced-update)
|
||||||
|
H: ... ...
|
||||||
|
H: flush-pkt
|
||||||
|
|
||||||
|
Each command for the 'proc-receive' hook may point to a pseudo-reference
|
||||||
|
and always has a zero-old as its old-oid, while the 'proc-receive' hook
|
||||||
|
may update an alternate reference and the alternate reference may exist
|
||||||
|
already with a non-zero old-oid. For this case, this hook will use
|
||||||
|
"option" directives to report extended attributes for the reference given
|
||||||
|
by the above "ok/ng" directive.
|
||||||
|
|
||||||
|
The report of the commands of this hook should have the same order as
|
||||||
|
the input. The exit status of the 'proc-receive' hook only determines
|
||||||
|
the success or failure of the group of commands sent to it, unless
|
||||||
|
atomic push is in use.
|
||||||
|
|
||||||
[[post-receive]]
|
[[post-receive]]
|
||||||
post-receive
|
post-receive
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
@ -503,8 +503,8 @@ The reference discovery phase is done nearly the same way as it is in the
|
|||||||
fetching protocol. Each reference obj-id and name on the server is sent
|
fetching protocol. Each reference obj-id and name on the server is sent
|
||||||
in packet-line format to the client, followed by a flush-pkt. The only
|
in packet-line format to the client, followed by a flush-pkt. The only
|
||||||
real difference is that the capability listing is different - the only
|
real difference is that the capability listing is different - the only
|
||||||
possible values are 'report-status', 'delete-refs', 'ofs-delta' and
|
possible values are 'report-status', 'report-status-v2', 'delete-refs',
|
||||||
'push-options'.
|
'ofs-delta', 'atomic' and 'push-options'.
|
||||||
|
|
||||||
Reference Update Request and Packfile Transfer
|
Reference Update Request and Packfile Transfer
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
@ -625,7 +625,7 @@ Report Status
|
|||||||
-------------
|
-------------
|
||||||
|
|
||||||
After receiving the pack data from the sender, the receiver sends a
|
After receiving the pack data from the sender, the receiver sends a
|
||||||
report if 'report-status' capability is in effect.
|
report if 'report-status' or 'report-status-v2' capability is in effect.
|
||||||
It is a short listing of what happened in that update. It will first
|
It is a short listing of what happened in that update. It will first
|
||||||
list the status of the packfile unpacking as either 'unpack ok' or
|
list the status of the packfile unpacking as either 'unpack ok' or
|
||||||
'unpack [error]'. Then it will list the status for each of the references
|
'unpack [error]'. Then it will list the status for each of the references
|
||||||
@ -647,6 +647,43 @@ update was successful, or 'ng [refname] [error]' if the update was not.
|
|||||||
error-msg = 1*(OCTET) ; where not "ok"
|
error-msg = 1*(OCTET) ; where not "ok"
|
||||||
----
|
----
|
||||||
|
|
||||||
|
New capability "report-status-v2" extends the protocol by adding new option
|
||||||
|
lines in order to support reporting of reference rewritten by the
|
||||||
|
"proc-receive" hook. The "proc-receive" hook may handle a command for a
|
||||||
|
pseudo-reference which may create or update one or more references, and each
|
||||||
|
reference may have different name, different new-oid, and different old-oid.
|
||||||
|
|
||||||
|
----
|
||||||
|
report-status-v2 = unpack-status
|
||||||
|
1*(command-status-v2)
|
||||||
|
flush-pkt
|
||||||
|
|
||||||
|
unpack-status = PKT-LINE("unpack" SP unpack-result)
|
||||||
|
unpack-result = "ok" / error-msg
|
||||||
|
|
||||||
|
command-status-v2 = command-ok-v2 / command-fail-v2
|
||||||
|
command-ok-v2 = command-ok
|
||||||
|
*option-line
|
||||||
|
command-fail-v2 = command-fail
|
||||||
|
*option-line
|
||||||
|
|
||||||
|
command-ok = PKT-LINE("ok" SP refname)
|
||||||
|
command-fail = PKT-LINE("ng" SP refname SP error-msg)
|
||||||
|
|
||||||
|
error-msg = 1*(OCTET) ; where not "ok"
|
||||||
|
|
||||||
|
option-line = *1(option-refname)
|
||||||
|
*1(option-old-oid)
|
||||||
|
*1(option-new-oid)
|
||||||
|
*1(option-forced-update)
|
||||||
|
|
||||||
|
option-refname = PKT-LINE("option" SP "refname" SP refname)
|
||||||
|
option-old-oid = PKT-LINE("option" SP "old-oid" SP obj-id)
|
||||||
|
option-new-oid = PKT-LINE("option" SP "new-oid" SP obj-id)
|
||||||
|
option-force = PKT-LINE("option" SP "forced-update")
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
Updates can be unsuccessful for a number of reasons. The reference can have
|
Updates can be unsuccessful for a number of reasons. The reference can have
|
||||||
changed since the reference discovery phase was originally sent, meaning
|
changed since the reference discovery phase was originally sent, meaning
|
||||||
someone pushed in the meantime. The reference being pushed could be a
|
someone pushed in the meantime. The reference being pushed could be a
|
||||||
|
@ -22,9 +22,9 @@ was sent. Server MUST NOT ignore capabilities that client requested
|
|||||||
and server advertised. As a consequence of these rules, server MUST
|
and server advertised. As a consequence of these rules, server MUST
|
||||||
NOT advertise capabilities it does not understand.
|
NOT advertise capabilities it does not understand.
|
||||||
|
|
||||||
The 'atomic', 'report-status', 'delete-refs', 'quiet', and 'push-cert'
|
The 'atomic', 'report-status', 'report-status-v2', 'delete-refs', 'quiet',
|
||||||
capabilities are sent and recognized by the receive-pack (push to server)
|
and 'push-cert' capabilities are sent and recognized by the receive-pack
|
||||||
process.
|
(push to server) process.
|
||||||
|
|
||||||
The 'ofs-delta' and 'side-band-64k' capabilities are sent and recognized
|
The 'ofs-delta' and 'side-band-64k' capabilities are sent and recognized
|
||||||
by both upload-pack and receive-pack protocols. The 'agent' capability
|
by both upload-pack and receive-pack protocols. The 'agent' capability
|
||||||
@ -284,6 +284,17 @@ each reference was updated successfully. If any of those were not
|
|||||||
successful, it will send back an error message. See pack-protocol.txt
|
successful, it will send back an error message. See pack-protocol.txt
|
||||||
for example messages.
|
for example messages.
|
||||||
|
|
||||||
|
report-status-v2
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Capability 'report-status-v2' extends capability 'report-status' by
|
||||||
|
adding new option lines in order to support reference rewritten by
|
||||||
|
the"proc-receive" hook. The "proc-receive" hook may handle a command
|
||||||
|
for a pseudo-reference which may create or update a reference with
|
||||||
|
different name, new-oid, and old-oid. While the capability
|
||||||
|
"report-status" cannot report for such case. See pack-protocol.txt
|
||||||
|
for details.
|
||||||
|
|
||||||
delete-refs
|
delete-refs
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
1
Makefile
1
Makefile
@ -719,6 +719,7 @@ TEST_BUILTINS_OBJS += test-parse-pathspec-file.o
|
|||||||
TEST_BUILTINS_OBJS += test-path-utils.o
|
TEST_BUILTINS_OBJS += test-path-utils.o
|
||||||
TEST_BUILTINS_OBJS += test-pkt-line.o
|
TEST_BUILTINS_OBJS += test-pkt-line.o
|
||||||
TEST_BUILTINS_OBJS += test-prio-queue.o
|
TEST_BUILTINS_OBJS += test-prio-queue.o
|
||||||
|
TEST_BUILTINS_OBJS += test-proc-receive.o
|
||||||
TEST_BUILTINS_OBJS += test-progress.o
|
TEST_BUILTINS_OBJS += test-progress.o
|
||||||
TEST_BUILTINS_OBJS += test-reach.o
|
TEST_BUILTINS_OBJS += test-reach.o
|
||||||
TEST_BUILTINS_OBJS += test-read-cache.o
|
TEST_BUILTINS_OBJS += test-read-cache.o
|
||||||
|
@ -57,6 +57,7 @@ static int advertise_push_options;
|
|||||||
static int unpack_limit = 100;
|
static int unpack_limit = 100;
|
||||||
static off_t max_input_size;
|
static off_t max_input_size;
|
||||||
static int report_status;
|
static int report_status;
|
||||||
|
static int report_status_v2;
|
||||||
static int use_sideband;
|
static int use_sideband;
|
||||||
static int use_atomic;
|
static int use_atomic;
|
||||||
static int use_push_options;
|
static int use_push_options;
|
||||||
@ -77,6 +78,7 @@ static struct object_id push_cert_oid;
|
|||||||
static struct signature_check sigcheck;
|
static struct signature_check sigcheck;
|
||||||
static const char *push_cert_nonce;
|
static const char *push_cert_nonce;
|
||||||
static const char *cert_nonce_seed;
|
static const char *cert_nonce_seed;
|
||||||
|
static struct string_list proc_receive_refs;
|
||||||
|
|
||||||
static const char *NONCE_UNSOLICITED = "UNSOLICITED";
|
static const char *NONCE_UNSOLICITED = "UNSOLICITED";
|
||||||
static const char *NONCE_BAD = "BAD";
|
static const char *NONCE_BAD = "BAD";
|
||||||
@ -229,6 +231,20 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcmp(var, "receive.procreceiverefs") == 0) {
|
||||||
|
char *prefix;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (!value)
|
||||||
|
return config_error_nonbool(var);
|
||||||
|
prefix = xstrdup(value);
|
||||||
|
len = strlen(prefix);
|
||||||
|
while (len && prefix[len - 1] == '/')
|
||||||
|
prefix[--len] = '\0';
|
||||||
|
string_list_append(&proc_receive_refs, prefix);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return git_default_config(var, value, cb);
|
return git_default_config(var, value, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +256,7 @@ static void show_ref(const char *path, const struct object_id *oid)
|
|||||||
struct strbuf cap = STRBUF_INIT;
|
struct strbuf cap = STRBUF_INIT;
|
||||||
|
|
||||||
strbuf_addstr(&cap,
|
strbuf_addstr(&cap,
|
||||||
"report-status delete-refs side-band-64k quiet");
|
"report-status report-status-v2 delete-refs side-band-64k quiet");
|
||||||
if (advertise_atomic_push)
|
if (advertise_atomic_push)
|
||||||
strbuf_addstr(&cap, " atomic");
|
strbuf_addstr(&cap, " atomic");
|
||||||
if (prefer_ofs_delta)
|
if (prefer_ofs_delta)
|
||||||
@ -310,11 +326,14 @@ static void write_head_info(void)
|
|||||||
packet_flush(1);
|
packet_flush(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RUN_PROC_RECEIVE_SCHEDULED 1
|
||||||
|
#define RUN_PROC_RECEIVE_RETURNED 2
|
||||||
struct command {
|
struct command {
|
||||||
struct command *next;
|
struct command *next;
|
||||||
const char *error_string;
|
struct ref_push_report report;
|
||||||
unsigned int skip_update:1,
|
unsigned int skip_update:1,
|
||||||
did_not_exist:1;
|
did_not_exist:1,
|
||||||
|
run_proc_receive:2;
|
||||||
int index;
|
int index;
|
||||||
struct object_id old_oid;
|
struct object_id old_oid;
|
||||||
struct object_id new_oid;
|
struct object_id new_oid;
|
||||||
@ -773,17 +792,38 @@ static int feed_receive_hook(void *state_, const char **bufp, size_t *sizep)
|
|||||||
{
|
{
|
||||||
struct receive_hook_feed_state *state = state_;
|
struct receive_hook_feed_state *state = state_;
|
||||||
struct command *cmd = state->cmd;
|
struct command *cmd = state->cmd;
|
||||||
|
static struct ref_push_report_options *options = NULL;
|
||||||
|
|
||||||
while (cmd &&
|
while (cmd &&
|
||||||
state->skip_broken && (cmd->error_string || cmd->did_not_exist))
|
state->skip_broken && (cmd->report.error_message || cmd->did_not_exist))
|
||||||
cmd = cmd->next;
|
cmd = cmd->next;
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return -1; /* EOF */
|
return -1; /* EOF */
|
||||||
|
if (!bufp)
|
||||||
|
return 0; /* OK, can feed something. */
|
||||||
strbuf_reset(&state->buf);
|
strbuf_reset(&state->buf);
|
||||||
strbuf_addf(&state->buf, "%s %s %s\n",
|
if (!options)
|
||||||
oid_to_hex(&cmd->old_oid), oid_to_hex(&cmd->new_oid),
|
options = cmd->report.options;
|
||||||
cmd->ref_name);
|
if (options) {
|
||||||
state->cmd = cmd->next;
|
struct object_id *old_oid;
|
||||||
|
struct object_id *new_oid;
|
||||||
|
const char *ref_name;
|
||||||
|
|
||||||
|
old_oid = options->old_oid ? options->old_oid : &cmd->old_oid;
|
||||||
|
new_oid = options->new_oid ? options->new_oid : &cmd->new_oid;
|
||||||
|
ref_name = options->ref_name ? options->ref_name : cmd->ref_name;
|
||||||
|
strbuf_addf(&state->buf, "%s %s %s\n",
|
||||||
|
oid_to_hex(old_oid), oid_to_hex(new_oid),
|
||||||
|
ref_name);
|
||||||
|
options = options->next;
|
||||||
|
if (!options)
|
||||||
|
state->cmd = cmd->next;
|
||||||
|
} else {
|
||||||
|
strbuf_addf(&state->buf, "%s %s %s\n",
|
||||||
|
oid_to_hex(&cmd->old_oid), oid_to_hex(&cmd->new_oid),
|
||||||
|
cmd->ref_name);
|
||||||
|
state->cmd = cmd->next;
|
||||||
|
}
|
||||||
if (bufp) {
|
if (bufp) {
|
||||||
*bufp = state->buf.buf;
|
*bufp = state->buf.buf;
|
||||||
*sizep = state->buf.len;
|
*sizep = state->buf.len;
|
||||||
@ -840,6 +880,268 @@ static int run_update_hook(struct command *cmd)
|
|||||||
return finish_command(&proc);
|
return finish_command(&proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct command *find_command_by_refname(const struct command *list,
|
||||||
|
const char *refname)
|
||||||
|
{
|
||||||
|
for (; list; list = list->next)
|
||||||
|
if (!strcmp(list->ref_name, refname))
|
||||||
|
return (struct command *)list;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_proc_receive_report(struct packet_reader *reader,
|
||||||
|
struct command *commands,
|
||||||
|
struct strbuf *errmsg)
|
||||||
|
{
|
||||||
|
struct command *cmd;
|
||||||
|
struct command *hint = NULL;
|
||||||
|
int code = 0;
|
||||||
|
int new_options = 1;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
struct object_id old_oid, new_oid;
|
||||||
|
const char *head;
|
||||||
|
const char *refname;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
head = reader->line;
|
||||||
|
p = strchr(head, ' ');
|
||||||
|
if (!p) {
|
||||||
|
strbuf_addf(errmsg, "proc-receive reported incomplete status line: '%s'\n", head);
|
||||||
|
code = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*p++ = '\0';
|
||||||
|
if (!strcmp(head, "option")) {
|
||||||
|
struct ref_push_report_options *options;
|
||||||
|
const char *key, *val;
|
||||||
|
|
||||||
|
if (!hint) {
|
||||||
|
if (new_options) {
|
||||||
|
strbuf_addstr(errmsg, "proc-receive reported 'option' without a matching 'ok/ng' directive\n");
|
||||||
|
new_options = 0;
|
||||||
|
}
|
||||||
|
code = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
options = hint->report.options;
|
||||||
|
while (options && options->next)
|
||||||
|
options = options->next;
|
||||||
|
if (new_options) {
|
||||||
|
if (!options) {
|
||||||
|
hint->report.options = xcalloc(1, sizeof(struct ref_push_report_options));
|
||||||
|
options = hint->report.options;
|
||||||
|
} else {
|
||||||
|
options->next = xcalloc(1, sizeof(struct ref_push_report_options));
|
||||||
|
options = options->next;
|
||||||
|
}
|
||||||
|
new_options = 0;
|
||||||
|
}
|
||||||
|
assert(options);
|
||||||
|
key = p;
|
||||||
|
p = strchr(key, ' ');
|
||||||
|
if (p)
|
||||||
|
*p++ = '\0';
|
||||||
|
val = p;
|
||||||
|
if (!strcmp(key, "refname"))
|
||||||
|
options->ref_name = xstrdup_or_null(val);
|
||||||
|
else if (!strcmp(key, "old-oid") && val &&
|
||||||
|
!parse_oid_hex(val, &old_oid, &val))
|
||||||
|
options->old_oid = oiddup(&old_oid);
|
||||||
|
else if (!strcmp(key, "new-oid") && val &&
|
||||||
|
!parse_oid_hex(val, &new_oid, &val))
|
||||||
|
options->new_oid = oiddup(&new_oid);
|
||||||
|
else if (!strcmp(key, "forced-update"))
|
||||||
|
options->forced_update = 1;
|
||||||
|
else if (!strcmp(key, "fall-through"))
|
||||||
|
/* Fall through, let 'receive-pack' to execute it. */
|
||||||
|
hint->run_proc_receive = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
refname = p;
|
||||||
|
p = strchr(refname, ' ');
|
||||||
|
if (p)
|
||||||
|
*p++ = '\0';
|
||||||
|
if (strcmp(head, "ok") && strcmp(head, "ng")) {
|
||||||
|
strbuf_addf(errmsg, "proc-receive reported bad status '%s' on ref '%s'\n",
|
||||||
|
head, refname);
|
||||||
|
code = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* first try searching at our hint, falling back to all refs */
|
||||||
|
if (hint)
|
||||||
|
hint = find_command_by_refname(hint, refname);
|
||||||
|
if (!hint)
|
||||||
|
hint = find_command_by_refname(commands, refname);
|
||||||
|
if (!hint) {
|
||||||
|
strbuf_addf(errmsg, "proc-receive reported status on unknown ref: %s\n",
|
||||||
|
refname);
|
||||||
|
code = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!hint->run_proc_receive) {
|
||||||
|
strbuf_addf(errmsg, "proc-receive reported status on unexpected ref: %s\n",
|
||||||
|
refname);
|
||||||
|
code = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strcmp(head, "ng")) {
|
||||||
|
if (p)
|
||||||
|
hint->report.error_message = xstrdup(p);
|
||||||
|
else
|
||||||
|
hint->report.error_message = "failed";
|
||||||
|
code = -1;
|
||||||
|
}
|
||||||
|
if (hint->run_proc_receive)
|
||||||
|
hint->run_proc_receive |= RUN_PROC_RECEIVE_RETURNED;
|
||||||
|
new_options = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cmd = commands; cmd; cmd = cmd->next)
|
||||||
|
if (cmd->run_proc_receive && !cmd->report.error_message &&
|
||||||
|
!(cmd->run_proc_receive & RUN_PROC_RECEIVE_RETURNED)) {
|
||||||
|
cmd->report.error_message = "proc-receive failed to report status";
|
||||||
|
code = -1;
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int run_proc_receive_hook(struct command *commands,
|
||||||
|
const struct string_list *push_options)
|
||||||
|
{
|
||||||
|
struct child_process proc = CHILD_PROCESS_INIT;
|
||||||
|
struct async muxer;
|
||||||
|
struct command *cmd;
|
||||||
|
const char *argv[2];
|
||||||
|
struct packet_reader reader;
|
||||||
|
struct strbuf cap = STRBUF_INIT;
|
||||||
|
struct strbuf errmsg = STRBUF_INIT;
|
||||||
|
int hook_use_push_options = 0;
|
||||||
|
int version = 0;
|
||||||
|
int code;
|
||||||
|
|
||||||
|
argv[0] = find_hook("proc-receive");
|
||||||
|
if (!argv[0]) {
|
||||||
|
rp_error("cannot find hook 'proc-receive'");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
argv[1] = NULL;
|
||||||
|
|
||||||
|
proc.argv = argv;
|
||||||
|
proc.in = -1;
|
||||||
|
proc.out = -1;
|
||||||
|
proc.trace2_hook_name = "proc-receive";
|
||||||
|
|
||||||
|
if (use_sideband) {
|
||||||
|
memset(&muxer, 0, sizeof(muxer));
|
||||||
|
muxer.proc = copy_to_sideband;
|
||||||
|
muxer.in = -1;
|
||||||
|
code = start_async(&muxer);
|
||||||
|
if (code)
|
||||||
|
return code;
|
||||||
|
proc.err = muxer.in;
|
||||||
|
} else {
|
||||||
|
proc.err = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = start_command(&proc);
|
||||||
|
if (code) {
|
||||||
|
if (use_sideband)
|
||||||
|
finish_async(&muxer);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
sigchain_push(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
|
/* Version negotiaton */
|
||||||
|
packet_reader_init(&reader, proc.out, NULL, 0,
|
||||||
|
PACKET_READ_CHOMP_NEWLINE |
|
||||||
|
PACKET_READ_GENTLE_ON_EOF);
|
||||||
|
if (use_atomic)
|
||||||
|
strbuf_addstr(&cap, " atomic");
|
||||||
|
if (use_push_options)
|
||||||
|
strbuf_addstr(&cap, " push-options");
|
||||||
|
if (cap.len) {
|
||||||
|
packet_write_fmt(proc.in, "version=1%c%s\n", '\0', cap.buf + 1);
|
||||||
|
strbuf_release(&cap);
|
||||||
|
} else {
|
||||||
|
packet_write_fmt(proc.in, "version=1\n");
|
||||||
|
}
|
||||||
|
packet_flush(proc.in);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
int linelen;
|
||||||
|
|
||||||
|
if (packet_reader_read(&reader) != PACKET_READ_NORMAL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (reader.pktlen > 8 && starts_with(reader.line, "version=")) {
|
||||||
|
version = atoi(reader.line + 8);
|
||||||
|
linelen = strlen(reader.line);
|
||||||
|
if (linelen < reader.pktlen) {
|
||||||
|
const char *feature_list = reader.line + linelen + 1;
|
||||||
|
if (parse_feature_request(feature_list, "push-options"))
|
||||||
|
hook_use_push_options = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version != 1) {
|
||||||
|
strbuf_addf(&errmsg, "proc-receive version '%d' is not supported",
|
||||||
|
version);
|
||||||
|
code = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send commands */
|
||||||
|
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||||
|
if (!cmd->run_proc_receive || cmd->skip_update || cmd->report.error_message)
|
||||||
|
continue;
|
||||||
|
packet_write_fmt(proc.in, "%s %s %s",
|
||||||
|
oid_to_hex(&cmd->old_oid),
|
||||||
|
oid_to_hex(&cmd->new_oid),
|
||||||
|
cmd->ref_name);
|
||||||
|
}
|
||||||
|
packet_flush(proc.in);
|
||||||
|
|
||||||
|
/* Send push options */
|
||||||
|
if (hook_use_push_options) {
|
||||||
|
struct string_list_item *item;
|
||||||
|
|
||||||
|
for_each_string_list_item(item, push_options)
|
||||||
|
packet_write_fmt(proc.in, "%s", item->string);
|
||||||
|
packet_flush(proc.in);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read result from proc-receive */
|
||||||
|
code = read_proc_receive_report(&reader, commands, &errmsg);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
close(proc.in);
|
||||||
|
close(proc.out);
|
||||||
|
if (use_sideband)
|
||||||
|
finish_async(&muxer);
|
||||||
|
if (finish_command(&proc))
|
||||||
|
code = -1;
|
||||||
|
if (errmsg.len >0) {
|
||||||
|
char *p = errmsg.buf;
|
||||||
|
|
||||||
|
p += errmsg.len - 1;
|
||||||
|
if (*p == '\n')
|
||||||
|
*p = '\0';
|
||||||
|
rp_error("%s", errmsg.buf);
|
||||||
|
strbuf_release(&errmsg);
|
||||||
|
}
|
||||||
|
sigchain_pop(SIGPIPE);
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static char *refuse_unconfigured_deny_msg =
|
static char *refuse_unconfigured_deny_msg =
|
||||||
N_("By default, updating the current branch in a non-bare repository\n"
|
N_("By default, updating the current branch in a non-bare repository\n"
|
||||||
"is denied, because it will make the index and work tree inconsistent\n"
|
"is denied, because it will make the index and work tree inconsistent\n"
|
||||||
@ -1203,7 +1505,7 @@ static void run_update_post_hook(struct command *commands)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||||
if (cmd->error_string || cmd->did_not_exist)
|
if (cmd->report.error_message || cmd->did_not_exist)
|
||||||
continue;
|
continue;
|
||||||
if (!proc.args.argc)
|
if (!proc.args.argc)
|
||||||
argv_array_push(&proc.args, hook);
|
argv_array_push(&proc.args, hook);
|
||||||
@ -1237,7 +1539,7 @@ static void check_aliased_update_internal(struct command *cmd,
|
|||||||
if (!dst_name) {
|
if (!dst_name) {
|
||||||
rp_error("refusing update to broken symref '%s'", cmd->ref_name);
|
rp_error("refusing update to broken symref '%s'", cmd->ref_name);
|
||||||
cmd->skip_update = 1;
|
cmd->skip_update = 1;
|
||||||
cmd->error_string = "broken symref";
|
cmd->report.error_message = "broken symref";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dst_name = strip_namespace(dst_name);
|
dst_name = strip_namespace(dst_name);
|
||||||
@ -1264,7 +1566,7 @@ static void check_aliased_update_internal(struct command *cmd,
|
|||||||
find_unique_abbrev(&dst_cmd->old_oid, DEFAULT_ABBREV),
|
find_unique_abbrev(&dst_cmd->old_oid, DEFAULT_ABBREV),
|
||||||
find_unique_abbrev(&dst_cmd->new_oid, DEFAULT_ABBREV));
|
find_unique_abbrev(&dst_cmd->new_oid, DEFAULT_ABBREV));
|
||||||
|
|
||||||
cmd->error_string = dst_cmd->error_string =
|
cmd->report.error_message = dst_cmd->report.error_message =
|
||||||
"inconsistent aliased update";
|
"inconsistent aliased update";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1293,7 +1595,7 @@ static void check_aliased_updates(struct command *commands)
|
|||||||
string_list_sort(&ref_list);
|
string_list_sort(&ref_list);
|
||||||
|
|
||||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||||
if (!cmd->error_string)
|
if (!cmd->report.error_message)
|
||||||
check_aliased_update(cmd, &ref_list);
|
check_aliased_update(cmd, &ref_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1330,7 +1632,7 @@ static void set_connectivity_errors(struct command *commands,
|
|||||||
&opt))
|
&opt))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cmd->error_string = "missing necessary objects";
|
cmd->report.error_message = "missing necessary objects";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1369,7 +1671,7 @@ static void reject_updates_to_hidden(struct command *commands)
|
|||||||
prefix_len = refname_full.len;
|
prefix_len = refname_full.len;
|
||||||
|
|
||||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||||
if (cmd->error_string)
|
if (cmd->report.error_message)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
strbuf_setlen(&refname_full, prefix_len);
|
strbuf_setlen(&refname_full, prefix_len);
|
||||||
@ -1378,9 +1680,9 @@ static void reject_updates_to_hidden(struct command *commands)
|
|||||||
if (!ref_is_hidden(cmd->ref_name, refname_full.buf))
|
if (!ref_is_hidden(cmd->ref_name, refname_full.buf))
|
||||||
continue;
|
continue;
|
||||||
if (is_null_oid(&cmd->new_oid))
|
if (is_null_oid(&cmd->new_oid))
|
||||||
cmd->error_string = "deny deleting a hidden ref";
|
cmd->report.error_message = "deny deleting a hidden ref";
|
||||||
else
|
else
|
||||||
cmd->error_string = "deny updating a hidden ref";
|
cmd->report.error_message = "deny updating a hidden ref";
|
||||||
}
|
}
|
||||||
|
|
||||||
strbuf_release(&refname_full);
|
strbuf_release(&refname_full);
|
||||||
@ -1388,7 +1690,7 @@ static void reject_updates_to_hidden(struct command *commands)
|
|||||||
|
|
||||||
static int should_process_cmd(struct command *cmd)
|
static int should_process_cmd(struct command *cmd)
|
||||||
{
|
{
|
||||||
return !cmd->error_string && !cmd->skip_update;
|
return !cmd->report.error_message && !cmd->skip_update;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void warn_if_skipped_connectivity_check(struct command *commands,
|
static void warn_if_skipped_connectivity_check(struct command *commands,
|
||||||
@ -1415,24 +1717,24 @@ static void execute_commands_non_atomic(struct command *commands,
|
|||||||
struct strbuf err = STRBUF_INIT;
|
struct strbuf err = STRBUF_INIT;
|
||||||
|
|
||||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||||
if (!should_process_cmd(cmd))
|
if (!should_process_cmd(cmd) || cmd->run_proc_receive)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
transaction = ref_transaction_begin(&err);
|
transaction = ref_transaction_begin(&err);
|
||||||
if (!transaction) {
|
if (!transaction) {
|
||||||
rp_error("%s", err.buf);
|
rp_error("%s", err.buf);
|
||||||
strbuf_reset(&err);
|
strbuf_reset(&err);
|
||||||
cmd->error_string = "transaction failed to start";
|
cmd->report.error_message = "transaction failed to start";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd->error_string = update(cmd, si);
|
cmd->report.error_message = update(cmd, si);
|
||||||
|
|
||||||
if (!cmd->error_string
|
if (!cmd->report.error_message
|
||||||
&& ref_transaction_commit(transaction, &err)) {
|
&& ref_transaction_commit(transaction, &err)) {
|
||||||
rp_error("%s", err.buf);
|
rp_error("%s", err.buf);
|
||||||
strbuf_reset(&err);
|
strbuf_reset(&err);
|
||||||
cmd->error_string = "failed to update ref";
|
cmd->report.error_message = "failed to update ref";
|
||||||
}
|
}
|
||||||
ref_transaction_free(transaction);
|
ref_transaction_free(transaction);
|
||||||
}
|
}
|
||||||
@ -1455,12 +1757,12 @@ static void execute_commands_atomic(struct command *commands,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||||
if (!should_process_cmd(cmd))
|
if (!should_process_cmd(cmd) || cmd->run_proc_receive)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cmd->error_string = update(cmd, si);
|
cmd->report.error_message = update(cmd, si);
|
||||||
|
|
||||||
if (cmd->error_string)
|
if (cmd->report.error_message)
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1473,8 +1775,8 @@ static void execute_commands_atomic(struct command *commands,
|
|||||||
|
|
||||||
failure:
|
failure:
|
||||||
for (cmd = commands; cmd; cmd = cmd->next)
|
for (cmd = commands; cmd; cmd = cmd->next)
|
||||||
if (!cmd->error_string)
|
if (!cmd->report.error_message)
|
||||||
cmd->error_string = reported_error;
|
cmd->report.error_message = reported_error;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
ref_transaction_free(transaction);
|
ref_transaction_free(transaction);
|
||||||
@ -1491,10 +1793,11 @@ static void execute_commands(struct command *commands,
|
|||||||
struct iterate_data data;
|
struct iterate_data data;
|
||||||
struct async muxer;
|
struct async muxer;
|
||||||
int err_fd = 0;
|
int err_fd = 0;
|
||||||
|
int run_proc_receive = 0;
|
||||||
|
|
||||||
if (unpacker_error) {
|
if (unpacker_error) {
|
||||||
for (cmd = commands; cmd; cmd = cmd->next)
|
for (cmd = commands; cmd; cmd = cmd->next)
|
||||||
cmd->error_string = "unpacker error";
|
cmd->report.error_message = "unpacker error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1520,10 +1823,36 @@ static void execute_commands(struct command *commands,
|
|||||||
|
|
||||||
reject_updates_to_hidden(commands);
|
reject_updates_to_hidden(commands);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to find commands that have special prefix in their reference names,
|
||||||
|
* and mark them to run an external "proc-receive" hook later.
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
|
||||||
|
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||||
|
if (!should_process_cmd(cmd))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
strbuf_setlen(&refname_full, prefix_len);
|
||||||
|
strbuf_addstr(&refname_full, cmd->ref_name);
|
||||||
|
if (ref_matches(&proc_receive_refs, cmd->ref_name, refname_full.buf)) {
|
||||||
|
cmd->run_proc_receive = RUN_PROC_RECEIVE_SCHEDULED;
|
||||||
|
run_proc_receive = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strbuf_release(&refname_full);
|
||||||
|
}
|
||||||
|
|
||||||
if (run_receive_hook(commands, "pre-receive", 0, push_options)) {
|
if (run_receive_hook(commands, "pre-receive", 0, push_options)) {
|
||||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||||
if (!cmd->error_string)
|
if (!cmd->report.error_message)
|
||||||
cmd->error_string = "pre-receive hook declined";
|
cmd->report.error_message = "pre-receive hook declined";
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1534,8 +1863,8 @@ static void execute_commands(struct command *commands,
|
|||||||
*/
|
*/
|
||||||
if (tmp_objdir_migrate(tmp_objdir) < 0) {
|
if (tmp_objdir_migrate(tmp_objdir) < 0) {
|
||||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||||
if (!cmd->error_string)
|
if (!cmd->report.error_message)
|
||||||
cmd->error_string = "unable to migrate objects to permanent storage";
|
cmd->report.error_message = "unable to migrate objects to permanent storage";
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1546,6 +1875,14 @@ static void execute_commands(struct command *commands,
|
|||||||
free(head_name_to_free);
|
free(head_name_to_free);
|
||||||
head_name = head_name_to_free = resolve_refdup("HEAD", 0, NULL, NULL);
|
head_name = head_name_to_free = resolve_refdup("HEAD", 0, NULL, NULL);
|
||||||
|
|
||||||
|
if (run_proc_receive &&
|
||||||
|
run_proc_receive_hook(commands, push_options))
|
||||||
|
for (cmd = commands; cmd; cmd = cmd->next)
|
||||||
|
if (!cmd->report.error_message &&
|
||||||
|
!(cmd->run_proc_receive & RUN_PROC_RECEIVE_RETURNED) &&
|
||||||
|
(cmd->run_proc_receive || use_atomic))
|
||||||
|
cmd->report.error_message = "fail to run proc-receive hook";
|
||||||
|
|
||||||
if (use_atomic)
|
if (use_atomic)
|
||||||
execute_commands_atomic(commands, si);
|
execute_commands_atomic(commands, si);
|
||||||
else
|
else
|
||||||
@ -1629,6 +1966,8 @@ static struct command *read_head_info(struct packet_reader *reader,
|
|||||||
int len = 0;
|
int len = 0;
|
||||||
if (parse_feature_request(feature_list, "report-status"))
|
if (parse_feature_request(feature_list, "report-status"))
|
||||||
report_status = 1;
|
report_status = 1;
|
||||||
|
if (parse_feature_request(feature_list, "report-status-v2"))
|
||||||
|
report_status_v2 = 1;
|
||||||
if (parse_feature_request(feature_list, "side-band-64k"))
|
if (parse_feature_request(feature_list, "side-band-64k"))
|
||||||
use_sideband = LARGE_PACKET_MAX;
|
use_sideband = LARGE_PACKET_MAX;
|
||||||
if (parse_feature_request(feature_list, "quiet"))
|
if (parse_feature_request(feature_list, "quiet"))
|
||||||
@ -1916,7 +2255,7 @@ static void update_shallow_info(struct command *commands,
|
|||||||
if (is_null_oid(&cmd->new_oid))
|
if (is_null_oid(&cmd->new_oid))
|
||||||
continue;
|
continue;
|
||||||
if (ref_status[cmd->index]) {
|
if (ref_status[cmd->index]) {
|
||||||
cmd->error_string = "shallow update not allowed";
|
cmd->report.error_message = "shallow update not allowed";
|
||||||
cmd->skip_update = 1;
|
cmd->skip_update = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1931,12 +2270,55 @@ static void report(struct command *commands, const char *unpack_status)
|
|||||||
packet_buf_write(&buf, "unpack %s\n",
|
packet_buf_write(&buf, "unpack %s\n",
|
||||||
unpack_status ? unpack_status : "ok");
|
unpack_status ? unpack_status : "ok");
|
||||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||||
if (!cmd->error_string)
|
if (!cmd->report.error_message)
|
||||||
packet_buf_write(&buf, "ok %s\n",
|
packet_buf_write(&buf, "ok %s\n",
|
||||||
cmd->ref_name);
|
cmd->ref_name);
|
||||||
else
|
else
|
||||||
packet_buf_write(&buf, "ng %s %s\n",
|
packet_buf_write(&buf, "ng %s %s\n",
|
||||||
cmd->ref_name, cmd->error_string);
|
cmd->ref_name, cmd->report.error_message);
|
||||||
|
}
|
||||||
|
packet_buf_flush(&buf);
|
||||||
|
|
||||||
|
if (use_sideband)
|
||||||
|
send_sideband(1, 1, buf.buf, buf.len, use_sideband);
|
||||||
|
else
|
||||||
|
write_or_die(1, buf.buf, buf.len);
|
||||||
|
strbuf_release(&buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void report_v2(struct command *commands, const char *unpack_status)
|
||||||
|
{
|
||||||
|
struct command *cmd;
|
||||||
|
struct strbuf buf = STRBUF_INIT;
|
||||||
|
struct ref_push_report_options *options;
|
||||||
|
|
||||||
|
packet_buf_write(&buf, "unpack %s\n",
|
||||||
|
unpack_status ? unpack_status : "ok");
|
||||||
|
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (!cmd->report.error_message)
|
||||||
|
packet_buf_write(&buf, "ok %s\n",
|
||||||
|
cmd->ref_name);
|
||||||
|
else
|
||||||
|
packet_buf_write(&buf, "ng %s %s\n",
|
||||||
|
cmd->ref_name,
|
||||||
|
cmd->report.error_message);
|
||||||
|
for (options = cmd->report.options; options; options = options->next) {
|
||||||
|
if (count++ > 0)
|
||||||
|
packet_buf_write(&buf, "ok %s\n", cmd->ref_name);
|
||||||
|
if (options->ref_name)
|
||||||
|
packet_buf_write(&buf, "option refname %s\n",
|
||||||
|
options->ref_name);
|
||||||
|
if (options->old_oid)
|
||||||
|
packet_buf_write(&buf, "option old-oid %s\n",
|
||||||
|
oid_to_hex(options->old_oid));
|
||||||
|
if (options->new_oid)
|
||||||
|
packet_buf_write(&buf, "option new-oid %s\n",
|
||||||
|
oid_to_hex(options->new_oid));
|
||||||
|
if (options->forced_update)
|
||||||
|
packet_buf_write(&buf, "option forced-update\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
packet_buf_flush(&buf);
|
packet_buf_flush(&buf);
|
||||||
|
|
||||||
@ -1974,6 +2356,8 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
|
|||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
string_list_init(&proc_receive_refs, 0);
|
||||||
|
|
||||||
packet_trace_identity("receive-pack");
|
packet_trace_identity("receive-pack");
|
||||||
|
|
||||||
argc = parse_options(argc, argv, prefix, options, receive_pack_usage, 0);
|
argc = parse_options(argc, argv, prefix, options, receive_pack_usage, 0);
|
||||||
@ -2040,7 +2424,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
|
|||||||
if (!check_cert_push_options(&push_options)) {
|
if (!check_cert_push_options(&push_options)) {
|
||||||
struct command *cmd;
|
struct command *cmd;
|
||||||
for (cmd = commands; cmd; cmd = cmd->next)
|
for (cmd = commands; cmd; cmd = cmd->next)
|
||||||
cmd->error_string = "inconsistent push options";
|
cmd->report.error_message = "inconsistent push options";
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare_shallow_info(&si, &shallow);
|
prepare_shallow_info(&si, &shallow);
|
||||||
@ -2055,7 +2439,9 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
|
|||||||
&push_options);
|
&push_options);
|
||||||
if (pack_lockfile)
|
if (pack_lockfile)
|
||||||
unlink_or_warn(pack_lockfile);
|
unlink_or_warn(pack_lockfile);
|
||||||
if (report_status)
|
if (report_status_v2)
|
||||||
|
report_v2(commands, unpack_status);
|
||||||
|
else if (report_status)
|
||||||
report(commands, unpack_status);
|
report(commands, unpack_status);
|
||||||
run_receive_hook(commands, "post-receive", 1,
|
run_receive_hook(commands, "post-receive", 1,
|
||||||
&push_options);
|
&push_options);
|
||||||
@ -2089,5 +2475,6 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
|
|||||||
oid_array_clear(&shallow);
|
oid_array_clear(&shallow);
|
||||||
oid_array_clear(&ref);
|
oid_array_clear(&ref);
|
||||||
free((void *)push_cert_nonce);
|
free((void *)push_cert_nonce);
|
||||||
|
string_list_clear(&proc_receive_refs, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,12 @@ static struct send_pack_args args;
|
|||||||
static void print_helper_status(struct ref *ref)
|
static void print_helper_status(struct ref *ref)
|
||||||
{
|
{
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
|
struct ref_push_report_options *options;
|
||||||
|
|
||||||
for (; ref; ref = ref->next) {
|
for (; ref; ref = ref->next) {
|
||||||
const char *msg = NULL;
|
const char *msg = NULL;
|
||||||
const char *res;
|
const char *res;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
switch(ref->status) {
|
switch(ref->status) {
|
||||||
case REF_STATUS_NONE:
|
case REF_STATUS_NONE:
|
||||||
@ -86,14 +88,29 @@ static void print_helper_status(struct ref *ref)
|
|||||||
|
|
||||||
strbuf_reset(&buf);
|
strbuf_reset(&buf);
|
||||||
strbuf_addf(&buf, "%s %s", res, ref->name);
|
strbuf_addf(&buf, "%s %s", res, ref->name);
|
||||||
if (ref->remote_status)
|
if (ref->report.error_message)
|
||||||
msg = ref->remote_status;
|
msg = ref->report.error_message;
|
||||||
if (msg) {
|
if (msg) {
|
||||||
strbuf_addch(&buf, ' ');
|
strbuf_addch(&buf, ' ');
|
||||||
quote_two_c_style(&buf, "", msg, 0);
|
quote_two_c_style(&buf, "", msg, 0);
|
||||||
}
|
}
|
||||||
strbuf_addch(&buf, '\n');
|
strbuf_addch(&buf, '\n');
|
||||||
|
|
||||||
|
for (options = ref->report.options; options; options = options->next) {
|
||||||
|
if (count++ > 0)
|
||||||
|
strbuf_addf(&buf, "ok %s\n", ref->name);
|
||||||
|
if (options->ref_name)
|
||||||
|
strbuf_addf(&buf, "option refname %s\n",
|
||||||
|
options->ref_name);
|
||||||
|
if (options->old_oid)
|
||||||
|
strbuf_addf(&buf, "option old-oid %s\n",
|
||||||
|
oid_to_hex(options->old_oid));
|
||||||
|
if (options->new_oid)
|
||||||
|
strbuf_addf(&buf, "option new-oid %s\n",
|
||||||
|
oid_to_hex(options->new_oid));
|
||||||
|
if (options->forced_update)
|
||||||
|
strbuf_addstr(&buf, "option forced-update\n");
|
||||||
|
}
|
||||||
write_or_die(1, buf.buf, buf.len);
|
write_or_die(1, buf.buf, buf.len);
|
||||||
}
|
}
|
||||||
strbuf_release(&buf);
|
strbuf_release(&buf);
|
||||||
|
13
refs.c
13
refs.c
@ -1346,14 +1346,14 @@ int parse_hide_refs_config(const char *var, const char *value, const char *secti
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ref_is_hidden(const char *refname, const char *refname_full)
|
int ref_matches(struct string_list *match_refs, const char *refname, const char *refname_full)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!hide_refs)
|
if (!match_refs)
|
||||||
return 0;
|
return 0;
|
||||||
for (i = hide_refs->nr - 1; i >= 0; i--) {
|
for (i = match_refs->nr - 1; i >= 0; i--) {
|
||||||
const char *match = hide_refs->items[i].string;
|
const char *match = match_refs->items[i].string;
|
||||||
const char *subject;
|
const char *subject;
|
||||||
int neg = 0;
|
int neg = 0;
|
||||||
const char *p;
|
const char *p;
|
||||||
@ -1379,6 +1379,11 @@ int ref_is_hidden(const char *refname, const char *refname_full)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ref_is_hidden(const char *refname, const char *refname_full)
|
||||||
|
{
|
||||||
|
return ref_matches(hide_refs, refname, refname_full);
|
||||||
|
}
|
||||||
|
|
||||||
const char *find_descendant_ref(const char *dirname,
|
const char *find_descendant_ref(const char *dirname,
|
||||||
const struct string_list *extras,
|
const struct string_list *extras,
|
||||||
const struct string_list *skip)
|
const struct string_list *skip)
|
||||||
|
1
refs.h
1
refs.h
@ -743,6 +743,7 @@ int parse_hide_refs_config(const char *var, const char *value, const char *);
|
|||||||
* parameter always points to the full ref name.
|
* parameter always points to the full ref name.
|
||||||
*/
|
*/
|
||||||
int ref_is_hidden(const char *, const char *);
|
int ref_is_hidden(const char *, const char *);
|
||||||
|
int ref_matches(struct string_list *, const char *, const char *);
|
||||||
|
|
||||||
enum ref_type {
|
enum ref_type {
|
||||||
REF_TYPE_PER_WORKTREE, /* refs inside refs/ but not shared */
|
REF_TYPE_PER_WORKTREE, /* refs inside refs/ but not shared */
|
||||||
|
4
remote.c
4
remote.c
@ -767,7 +767,7 @@ struct ref *copy_ref(const struct ref *ref)
|
|||||||
memcpy(cpy, ref, len);
|
memcpy(cpy, ref, len);
|
||||||
cpy->next = NULL;
|
cpy->next = NULL;
|
||||||
cpy->symref = xstrdup_or_null(ref->symref);
|
cpy->symref = xstrdup_or_null(ref->symref);
|
||||||
cpy->remote_status = xstrdup_or_null(ref->remote_status);
|
cpy->report.error_message = xstrdup_or_null(ref->report.error_message);
|
||||||
cpy->peer_ref = copy_ref(ref->peer_ref);
|
cpy->peer_ref = copy_ref(ref->peer_ref);
|
||||||
return cpy;
|
return cpy;
|
||||||
}
|
}
|
||||||
@ -789,7 +789,7 @@ void free_one_ref(struct ref *ref)
|
|||||||
if (!ref)
|
if (!ref)
|
||||||
return;
|
return;
|
||||||
free_one_ref(ref->peer_ref);
|
free_one_ref(ref->peer_ref);
|
||||||
free(ref->remote_status);
|
free((void *)ref->report.error_message);
|
||||||
free(ref->symref);
|
free(ref->symref);
|
||||||
free(ref);
|
free(ref);
|
||||||
}
|
}
|
||||||
|
16
remote.h
16
remote.h
@ -93,6 +93,20 @@ int for_each_remote(each_remote_fn fn, void *priv);
|
|||||||
|
|
||||||
int remote_has_url(struct remote *remote, const char *url);
|
int remote_has_url(struct remote *remote, const char *url);
|
||||||
|
|
||||||
|
struct ref_push_report_options {
|
||||||
|
const char *ref_name;
|
||||||
|
struct object_id *old_oid;
|
||||||
|
struct object_id *new_oid;
|
||||||
|
unsigned int forced_update:1;
|
||||||
|
struct ref_push_report_options *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ref_push_report {
|
||||||
|
const char *message;
|
||||||
|
const char *error_message;
|
||||||
|
struct ref_push_report_options *options;
|
||||||
|
};
|
||||||
|
|
||||||
struct ref {
|
struct ref {
|
||||||
struct ref *next;
|
struct ref *next;
|
||||||
struct object_id old_oid;
|
struct object_id old_oid;
|
||||||
@ -139,7 +153,7 @@ struct ref {
|
|||||||
REF_STATUS_EXPECTING_REPORT,
|
REF_STATUS_EXPECTING_REPORT,
|
||||||
REF_STATUS_ATOMIC_PUSH_FAILED
|
REF_STATUS_ATOMIC_PUSH_FAILED
|
||||||
} status;
|
} status;
|
||||||
char *remote_status;
|
struct ref_push_report report;
|
||||||
struct ref *peer_ref; /* when renaming */
|
struct ref *peer_ref; /* when renaming */
|
||||||
char name[FLEX_ARRAY]; /* more */
|
char name[FLEX_ARRAY]; /* more */
|
||||||
};
|
};
|
||||||
|
97
send-pack.c
97
send-pack.c
@ -154,25 +154,79 @@ static int receive_status(struct packet_reader *reader, struct ref *refs)
|
|||||||
{
|
{
|
||||||
struct ref *hint;
|
struct ref *hint;
|
||||||
int ret;
|
int ret;
|
||||||
|
int new_options = 1;
|
||||||
|
|
||||||
hint = NULL;
|
hint = NULL;
|
||||||
ret = receive_unpack_status(reader);
|
ret = receive_unpack_status(reader);
|
||||||
while (1) {
|
while (1) {
|
||||||
|
struct object_id old_oid, new_oid;
|
||||||
|
const char *head;
|
||||||
const char *refname;
|
const char *refname;
|
||||||
char *msg;
|
char *p;
|
||||||
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||||
break;
|
break;
|
||||||
if (!starts_with(reader->line, "ok ") && !starts_with(reader->line, "ng ")) {
|
head = reader->line;
|
||||||
error("invalid ref status from remote: %s", reader->line);
|
p = strchr(head, ' ');
|
||||||
|
if (!p) {
|
||||||
|
error("invalid status line from remote: %s", reader->line);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
*p++ = '\0';
|
||||||
|
|
||||||
refname = reader->line + 3;
|
if (!strcmp(head, "option")) {
|
||||||
msg = strchr(refname, ' ');
|
struct ref_push_report_options *options;
|
||||||
if (msg)
|
const char *key, *val;
|
||||||
*msg++ = '\0';
|
|
||||||
|
|
||||||
|
if (!hint) {
|
||||||
|
if (new_options) {
|
||||||
|
error("'option' without a matching 'ok/ng' directive");
|
||||||
|
new_options = 0;
|
||||||
|
}
|
||||||
|
ret = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
options = hint->report.options;
|
||||||
|
while (options && options->next)
|
||||||
|
options = options->next;
|
||||||
|
if (new_options) {
|
||||||
|
if (!options) {
|
||||||
|
hint->report.options = xcalloc(1, sizeof(struct ref_push_report_options));
|
||||||
|
options = hint->report.options;
|
||||||
|
} else {
|
||||||
|
options->next = xcalloc(1, sizeof(struct ref_push_report_options));
|
||||||
|
options = options->next;
|
||||||
|
}
|
||||||
|
new_options = 0;
|
||||||
|
}
|
||||||
|
assert(options);
|
||||||
|
key = p;
|
||||||
|
p = strchr(key, ' ');
|
||||||
|
if (p)
|
||||||
|
*p++ = '\0';
|
||||||
|
val = p;
|
||||||
|
if (!strcmp(key, "refname"))
|
||||||
|
options->ref_name = xstrdup_or_null(val);
|
||||||
|
else if (!strcmp(key, "old-oid") && val &&
|
||||||
|
!parse_oid_hex(val, &old_oid, &val))
|
||||||
|
options->old_oid = oiddup(&old_oid);
|
||||||
|
else if (!strcmp(key, "new-oid") && val &&
|
||||||
|
!parse_oid_hex(val, &new_oid, &val))
|
||||||
|
options->new_oid = oiddup(&new_oid);
|
||||||
|
else if (!strcmp(key, "forced-update"))
|
||||||
|
options->forced_update = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(head, "ok") && strcmp(head, "ng")) {
|
||||||
|
error("invalid ref status from remote: %s", head);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
refname = p;
|
||||||
|
p = strchr(refname, ' ');
|
||||||
|
if (p)
|
||||||
|
*p++ = '\0';
|
||||||
/* first try searching at our hint, falling back to all refs */
|
/* first try searching at our hint, falling back to all refs */
|
||||||
if (hint)
|
if (hint)
|
||||||
hint = find_ref_by_name(hint, refname);
|
hint = find_ref_by_name(hint, refname);
|
||||||
@ -183,19 +237,24 @@ static int receive_status(struct packet_reader *reader, struct ref *refs)
|
|||||||
refname);
|
refname);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (hint->status != REF_STATUS_EXPECTING_REPORT) {
|
if (hint->status != REF_STATUS_EXPECTING_REPORT &&
|
||||||
|
hint->status != REF_STATUS_OK &&
|
||||||
|
hint->status != REF_STATUS_REMOTE_REJECT) {
|
||||||
warning("remote reported status on unexpected ref: %s",
|
warning("remote reported status on unexpected ref: %s",
|
||||||
refname);
|
refname);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp(head, "ng")) {
|
||||||
if (reader->line[0] == 'o' && reader->line[1] == 'k')
|
|
||||||
hint->status = REF_STATUS_OK;
|
|
||||||
else
|
|
||||||
hint->status = REF_STATUS_REMOTE_REJECT;
|
hint->status = REF_STATUS_REMOTE_REJECT;
|
||||||
hint->remote_status = xstrdup_or_null(msg);
|
if (p)
|
||||||
/* start our next search from the next ref */
|
hint->report.error_message = xstrdup(p);
|
||||||
hint = hint->next;
|
else
|
||||||
|
hint->report.error_message = "failed";
|
||||||
|
} else {
|
||||||
|
hint->status = REF_STATUS_OK;
|
||||||
|
hint->report.message = xstrdup_or_null(p);
|
||||||
|
}
|
||||||
|
new_options = 1;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -371,7 +430,9 @@ int send_pack(struct send_pack_args *args,
|
|||||||
struct packet_reader reader;
|
struct packet_reader reader;
|
||||||
|
|
||||||
/* Does the other end support the reporting? */
|
/* Does the other end support the reporting? */
|
||||||
if (server_supports("report-status"))
|
if (server_supports("report-status-v2"))
|
||||||
|
status_report = 2;
|
||||||
|
else if (server_supports("report-status"))
|
||||||
status_report = 1;
|
status_report = 1;
|
||||||
if (server_supports("delete-refs"))
|
if (server_supports("delete-refs"))
|
||||||
allow_deleting_refs = 1;
|
allow_deleting_refs = 1;
|
||||||
@ -423,8 +484,10 @@ int send_pack(struct send_pack_args *args,
|
|||||||
|
|
||||||
use_push_options = push_options_supported && args->push_options;
|
use_push_options = push_options_supported && args->push_options;
|
||||||
|
|
||||||
if (status_report)
|
if (status_report == 1)
|
||||||
strbuf_addstr(&cap_buf, " report-status");
|
strbuf_addstr(&cap_buf, " report-status");
|
||||||
|
else if (status_report == 2)
|
||||||
|
strbuf_addstr(&cap_buf, " report-status-v2");
|
||||||
if (use_sideband)
|
if (use_sideband)
|
||||||
strbuf_addstr(&cap_buf, " side-band-64k");
|
strbuf_addstr(&cap_buf, " side-band-64k");
|
||||||
if (quiet_supported && (args->quiet || !args->progress))
|
if (quiet_supported && (args->quiet || !args->progress))
|
||||||
|
174
t/helper/test-proc-receive.c
Normal file
174
t/helper/test-proc-receive.c
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
#include "cache.h"
|
||||||
|
#include "connect.h"
|
||||||
|
#include "parse-options.h"
|
||||||
|
#include "pkt-line.h"
|
||||||
|
#include "sigchain.h"
|
||||||
|
#include "test-tool.h"
|
||||||
|
|
||||||
|
static const char *proc_receive_usage[] = {
|
||||||
|
"test-tool proc-receive [<options>...]",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
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 {
|
||||||
|
struct command *next;
|
||||||
|
const char *error_string;
|
||||||
|
unsigned int skip_update:1,
|
||||||
|
did_not_exist:1;
|
||||||
|
int index;
|
||||||
|
struct object_id old_oid;
|
||||||
|
struct object_id new_oid;
|
||||||
|
char ref_name[FLEX_ARRAY]; /* more */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void proc_receive_verison(struct packet_reader *reader) {
|
||||||
|
int server_version = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
int linelen;
|
||||||
|
|
||||||
|
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (reader->pktlen > 8 && starts_with(reader->line, "version=")) {
|
||||||
|
server_version = atoi(reader->line+8);
|
||||||
|
linelen = strlen(reader->line);
|
||||||
|
if (linelen < reader->pktlen) {
|
||||||
|
const char *feature_list = reader->line + linelen + 1;
|
||||||
|
if (parse_feature_request(feature_list, "atomic"))
|
||||||
|
use_atomic= 1;
|
||||||
|
if (parse_feature_request(feature_list, "push-options"))
|
||||||
|
use_push_options = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server_version != 1 || die_version)
|
||||||
|
die("bad protocol version: %d", server_version);
|
||||||
|
|
||||||
|
packet_write_fmt(1, "version=%d%c%s\n",
|
||||||
|
version, '\0',
|
||||||
|
use_push_options && !no_push_options ? "push-options": "");
|
||||||
|
packet_flush(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void proc_receive_read_commands(struct packet_reader *reader,
|
||||||
|
struct command **commands)
|
||||||
|
{
|
||||||
|
struct command **tail = commands;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
struct object_id old_oid, new_oid;
|
||||||
|
struct command *cmd;
|
||||||
|
const char *refname;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (parse_oid_hex(reader->line, &old_oid, &p) ||
|
||||||
|
*p++ != ' ' ||
|
||||||
|
parse_oid_hex(p, &new_oid, &p) ||
|
||||||
|
*p++ != ' ' ||
|
||||||
|
die_readline)
|
||||||
|
die("protocol error: expected 'old new ref', got '%s'",
|
||||||
|
reader->line);
|
||||||
|
refname = p;
|
||||||
|
FLEX_ALLOC_STR(cmd, ref_name, refname);
|
||||||
|
oidcpy(&cmd->old_oid, &old_oid);
|
||||||
|
oidcpy(&cmd->new_oid, &new_oid);
|
||||||
|
|
||||||
|
*tail = cmd;
|
||||||
|
tail = &cmd->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void proc_receive_read_push_options(struct packet_reader *reader,
|
||||||
|
struct string_list *options)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (no_push_options || !use_push_options)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
string_list_append(options, reader->line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd__proc_receive(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
struct packet_reader reader;
|
||||||
|
struct command *commands = NULL;
|
||||||
|
struct string_list push_options = STRING_LIST_INIT_DUP;
|
||||||
|
struct string_list_item *item;
|
||||||
|
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"),
|
||||||
|
OPT_INTEGER('V', "version", &version,
|
||||||
|
"use this protocol version number"),
|
||||||
|
OPT_END()
|
||||||
|
};
|
||||||
|
|
||||||
|
argc = parse_options(argc, argv, "test-tools", options, proc_receive_usage, 0);
|
||||||
|
if (argc > 0)
|
||||||
|
usage_msg_opt("Too many arguments.", proc_receive_usage, options);
|
||||||
|
|
||||||
|
packet_reader_init(&reader, 0, NULL, 0,
|
||||||
|
PACKET_READ_CHOMP_NEWLINE |
|
||||||
|
PACKET_READ_DIE_ON_ERR_PACKET);
|
||||||
|
|
||||||
|
sigchain_push(SIGPIPE, SIG_IGN);
|
||||||
|
proc_receive_verison(&reader);
|
||||||
|
proc_receive_read_commands(&reader, &commands);
|
||||||
|
proc_receive_read_push_options(&reader, &push_options);
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
struct command *cmd;
|
||||||
|
|
||||||
|
if (use_push_options || use_atomic)
|
||||||
|
fprintf(stderr, "proc-receive:%s%s\n",
|
||||||
|
use_atomic? " atomic": "",
|
||||||
|
use_push_options ? " push_options": "");
|
||||||
|
|
||||||
|
for (cmd = commands; cmd; cmd = cmd->next)
|
||||||
|
fprintf(stderr, "proc-receive< %s %s %s\n",
|
||||||
|
oid_to_hex(&cmd->old_oid),
|
||||||
|
oid_to_hex(&cmd->new_oid),
|
||||||
|
cmd->ref_name);
|
||||||
|
|
||||||
|
if (push_options.nr > 0)
|
||||||
|
for_each_string_list_item(item, &push_options)
|
||||||
|
fprintf(stderr, "proc-receive< %s\n", item->string);
|
||||||
|
|
||||||
|
if (returns.nr)
|
||||||
|
for_each_string_list_item(item, &returns)
|
||||||
|
fprintf(stderr, "proc-receive> %s\n", item->string);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returns.nr)
|
||||||
|
for_each_string_list_item(item, &returns)
|
||||||
|
packet_write_fmt(1, "%s\n", item->string);
|
||||||
|
packet_flush(1);
|
||||||
|
sigchain_pop(SIGPIPE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -46,6 +46,7 @@ static struct test_cmd cmds[] = {
|
|||||||
{ "path-utils", cmd__path_utils },
|
{ "path-utils", cmd__path_utils },
|
||||||
{ "pkt-line", cmd__pkt_line },
|
{ "pkt-line", cmd__pkt_line },
|
||||||
{ "prio-queue", cmd__prio_queue },
|
{ "prio-queue", cmd__prio_queue },
|
||||||
|
{ "proc-receive", cmd__proc_receive},
|
||||||
{ "progress", cmd__progress },
|
{ "progress", cmd__progress },
|
||||||
{ "reach", cmd__reach },
|
{ "reach", cmd__reach },
|
||||||
{ "read-cache", cmd__read_cache },
|
{ "read-cache", cmd__read_cache },
|
||||||
|
@ -35,6 +35,7 @@ int cmd__parse_pathspec_file(int argc, const char** argv);
|
|||||||
int cmd__path_utils(int argc, const char **argv);
|
int cmd__path_utils(int argc, const char **argv);
|
||||||
int cmd__pkt_line(int argc, const char **argv);
|
int cmd__pkt_line(int argc, const char **argv);
|
||||||
int cmd__prio_queue(int argc, const char **argv);
|
int cmd__prio_queue(int argc, const char **argv);
|
||||||
|
int cmd__proc_receive(int argc, const char **argv);
|
||||||
int cmd__progress(int argc, const char **argv);
|
int cmd__progress(int argc, const char **argv);
|
||||||
int cmd__reach(int argc, const char **argv);
|
int cmd__reach(int argc, const char **argv);
|
||||||
int cmd__read_cache(int argc, const char **argv);
|
int cmd__read_cache(int argc, const char **argv);
|
||||||
|
117
t/t5411-proc-receive-hook.sh
Executable file
117
t/t5411-proc-receive-hook.sh
Executable file
@ -0,0 +1,117 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 Jiang Xin
|
||||||
|
#
|
||||||
|
|
||||||
|
test_description='Test proc-receive hook'
|
||||||
|
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
. "$TEST_DIRECTORY"/t5411/common-functions.sh
|
||||||
|
|
||||||
|
setup_upstream_and_workbench () {
|
||||||
|
# Refs of upstream : master(A)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
test_expect_success "setup upstream and workbench" '
|
||||||
|
rm -rf upstream.git &&
|
||||||
|
rm -rf workbench &&
|
||||||
|
git init --bare upstream.git &&
|
||||||
|
git init workbench &&
|
||||||
|
create_commits_in workbench A B &&
|
||||||
|
(
|
||||||
|
cd workbench &&
|
||||||
|
# Try to make a stable fixed width for abbreviated commit ID,
|
||||||
|
# this fixed-width oid will be replaced with "<OID>".
|
||||||
|
git config core.abbrev 7 &&
|
||||||
|
git tag -m "v123" v123 $A &&
|
||||||
|
git remote add origin ../upstream.git &&
|
||||||
|
git push origin master &&
|
||||||
|
git update-ref refs/heads/master $A $B &&
|
||||||
|
git -C ../upstream.git update-ref \
|
||||||
|
refs/heads/master $A $B
|
||||||
|
) &&
|
||||||
|
TAG=$(git -C workbench rev-parse v123) &&
|
||||||
|
|
||||||
|
# setup pre-receive hook
|
||||||
|
write_script upstream.git/hooks/pre-receive <<-\EOF &&
|
||||||
|
exec >&2
|
||||||
|
echo "# pre-receive hook"
|
||||||
|
while read old new ref
|
||||||
|
do
|
||||||
|
echo "pre-receive< $old $new $ref"
|
||||||
|
done
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# setup post-receive hook
|
||||||
|
write_script upstream.git/hooks/post-receive <<-\EOF &&
|
||||||
|
exec >&2
|
||||||
|
echo "# post-receive hook"
|
||||||
|
while read old new ref
|
||||||
|
do
|
||||||
|
echo "post-receive< $old $new $ref"
|
||||||
|
done
|
||||||
|
EOF
|
||||||
|
|
||||||
|
upstream=upstream.git
|
||||||
|
'
|
||||||
|
}
|
||||||
|
|
||||||
|
run_proc_receive_hook_test() {
|
||||||
|
case $1 in
|
||||||
|
http)
|
||||||
|
PROTOCOL="HTTP protocol"
|
||||||
|
URL_PREFIX="http://.*"
|
||||||
|
;;
|
||||||
|
local)
|
||||||
|
PROTOCOL="builtin protocol"
|
||||||
|
URL_PREFIX="\.\."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Include test cases for both file and HTTP protocol
|
||||||
|
for t in "$TEST_DIRECTORY"/t5411/test-*.sh
|
||||||
|
do
|
||||||
|
. "$t"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Initialize the upstream repository and local workbench.
|
||||||
|
setup_upstream_and_workbench
|
||||||
|
|
||||||
|
# Load test cases that only need to be executed once.
|
||||||
|
for t in "$TEST_DIRECTORY"/t5411/once-*.sh
|
||||||
|
do
|
||||||
|
. "$t"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Initialize the upstream repository and local workbench.
|
||||||
|
setup_upstream_and_workbench
|
||||||
|
|
||||||
|
# Run test cases for 'proc-receive' hook on local file protocol.
|
||||||
|
run_proc_receive_hook_test local
|
||||||
|
|
||||||
|
ROOT_PATH="$PWD"
|
||||||
|
. "$TEST_DIRECTORY"/lib-gpg.sh
|
||||||
|
. "$TEST_DIRECTORY"/lib-httpd.sh
|
||||||
|
. "$TEST_DIRECTORY"/lib-terminal.sh
|
||||||
|
start_httpd
|
||||||
|
|
||||||
|
# Re-initialize the upstream repository and local workbench.
|
||||||
|
setup_upstream_and_workbench
|
||||||
|
|
||||||
|
# Refs of upstream : master(A)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
test_expect_success "setup for HTTP protocol" '
|
||||||
|
git -C upstream.git config http.receivepack true &&
|
||||||
|
upstream="$HTTPD_DOCUMENT_ROOT_PATH/upstream.git" &&
|
||||||
|
mv upstream.git "$upstream" &&
|
||||||
|
git -C workbench remote set-url origin "$HTTPD_URL/auth-push/smart/upstream.git" &&
|
||||||
|
set_askpass user@host pass@host
|
||||||
|
'
|
||||||
|
|
||||||
|
setup_askpass_helper
|
||||||
|
|
||||||
|
# Run test cases for 'proc-receive' hook on HTTP protocol.
|
||||||
|
run_proc_receive_hook_test http
|
||||||
|
|
||||||
|
test_done
|
56
t/t5411/common-functions.sh
Normal file
56
t/t5411/common-functions.sh
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# Create commits in <repo> and assign each commit's oid to shell variables
|
||||||
|
# given in the arguments (A, B, and C). E.g.:
|
||||||
|
#
|
||||||
|
# create_commits_in <repo> A B C
|
||||||
|
#
|
||||||
|
# NOTE: Never calling this function from a subshell since variable
|
||||||
|
# assignments will disappear when subshell exits.
|
||||||
|
create_commits_in () {
|
||||||
|
repo="$1" &&
|
||||||
|
if ! parent=$(git -C "$repo" rev-parse HEAD^{} --)
|
||||||
|
then
|
||||||
|
parent=
|
||||||
|
fi &&
|
||||||
|
T=$(git -C "$repo" write-tree) &&
|
||||||
|
shift &&
|
||||||
|
while test $# -gt 0
|
||||||
|
do
|
||||||
|
name=$1 &&
|
||||||
|
test_tick &&
|
||||||
|
if test -z "$parent"
|
||||||
|
then
|
||||||
|
oid=$(echo $name | git -C "$repo" commit-tree $T)
|
||||||
|
else
|
||||||
|
oid=$(echo $name | git -C "$repo" commit-tree -p $parent $T)
|
||||||
|
fi &&
|
||||||
|
eval $name=$oid &&
|
||||||
|
parent=$oid &&
|
||||||
|
shift ||
|
||||||
|
return 1
|
||||||
|
done &&
|
||||||
|
git -C "$repo" update-ref refs/heads/master $oid
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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. 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 () {
|
||||||
|
sed \
|
||||||
|
-e "s/ *\$//" \
|
||||||
|
-e "s/ */ /g" \
|
||||||
|
-e "s/'/\"/g" \
|
||||||
|
-e "s/ / /g" \
|
||||||
|
-e "s/$A/<COMMIT-A>/g" \
|
||||||
|
-e "s/$B/<COMMIT-B>/g" \
|
||||||
|
-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#To $URL_PREFIX/upstream.git#To <URL/of/upstream.git>#" \
|
||||||
|
-e "/^error: / d"
|
||||||
|
}
|
88
t/t5411/once-0010-report-status-v1.sh
Normal file
88
t/t5411/once-0010-report-status-v1.sh
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
test_expect_success "setup receive.procReceiveRefs" '
|
||||||
|
git -C "$upstream" config --add receive.procReceiveRefs refs/for
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook" '
|
||||||
|
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||||
|
printf >&2 "# proc-receive hook\n"
|
||||||
|
test-tool proc-receive -v \
|
||||||
|
-r "ok refs/for/master/topic1" \
|
||||||
|
-r "option fall-through" \
|
||||||
|
-r "ok refs/for/master/topic2" \
|
||||||
|
-r "option refname refs/for/changes/23/123/1" \
|
||||||
|
-r "option new-oid $A" \
|
||||||
|
-r "ok refs/for/master/topic2" \
|
||||||
|
-r "option refname refs/for/changes/24/124/2" \
|
||||||
|
-r "option old-oid $B" \
|
||||||
|
-r "option new-oid $A" \
|
||||||
|
-r "option forced-update" \
|
||||||
|
-r "ng refs/for/next/topic target branch not exist"
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
|
||||||
|
# Refs of upstream : master(A)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
# git push : (B) refs/for/master/topic1(A) foo(A) refs/for/next/topic(A) refs/for/master/topic2(A)
|
||||||
|
test_expect_success "proc-receive: report status v1" '
|
||||||
|
{
|
||||||
|
printf "%s %s refs/heads/master\0report-status\n" \
|
||||||
|
$A $B | packetize &&
|
||||||
|
printf "%s %s refs/for/master/topic1\n" \
|
||||||
|
$ZERO_OID $A | packetize &&
|
||||||
|
printf "%s %s refs/heads/foo\n" \
|
||||||
|
$ZERO_OID $A | packetize &&
|
||||||
|
printf "%s %s refs/for/next/topic\n" \
|
||||||
|
$ZERO_OID $A | packetize &&
|
||||||
|
printf "%s %s refs/for/master/topic2\n" \
|
||||||
|
$ZERO_OID $A | packetize &&
|
||||||
|
printf 0000 &&
|
||||||
|
printf "" | git -C "$upstream" pack-objects --stdout
|
||||||
|
} | git receive-pack "$upstream" --stateless-rpc \
|
||||||
|
>out 2>&1 &&
|
||||||
|
make_user_friendly_and_stable_output <out >actual &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
# pre-receive hook
|
||||||
|
pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||||
|
pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic1
|
||||||
|
pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo
|
||||||
|
pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
|
||||||
|
pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic2
|
||||||
|
# proc-receive hook
|
||||||
|
proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic1
|
||||||
|
proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
|
||||||
|
proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic2
|
||||||
|
proc-receive> ok refs/for/master/topic1
|
||||||
|
proc-receive> option fall-through
|
||||||
|
proc-receive> ok refs/for/master/topic2
|
||||||
|
proc-receive> option refname refs/for/changes/23/123/1
|
||||||
|
proc-receive> option new-oid <COMMIT-A>
|
||||||
|
proc-receive> ok refs/for/master/topic2
|
||||||
|
proc-receive> option refname refs/for/changes/24/124/2
|
||||||
|
proc-receive> option old-oid <COMMIT-B>
|
||||||
|
proc-receive> option new-oid <COMMIT-A>
|
||||||
|
proc-receive> option forced-update
|
||||||
|
proc-receive> ng refs/for/next/topic target branch not exist
|
||||||
|
000eunpack ok
|
||||||
|
0019ok refs/heads/master
|
||||||
|
001eok refs/for/master/topic1
|
||||||
|
0016ok refs/heads/foo
|
||||||
|
0033ng refs/for/next/topic target branch not exist
|
||||||
|
001eok refs/for/master/topic2
|
||||||
|
0000# post-receive hook
|
||||||
|
post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||||
|
post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic1
|
||||||
|
post-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo
|
||||||
|
post-receive< <ZERO-OID> <COMMIT-A> refs/for/changes/23/123/1
|
||||||
|
post-receive< <COMMIT-B> <COMMIT-A> refs/for/changes/24/124/2
|
||||||
|
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/for/master/topic1
|
||||||
|
<COMMIT-A> refs/heads/foo
|
||||||
|
<COMMIT-B> refs/heads/master
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
143
t/t5411/test-0000-standard-git-push.sh
Normal file
143
t/t5411/test-0000-standard-git-push.sh
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
# Refs of upstream : master(A)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
# git-push : master(B) next(A)
|
||||||
|
test_expect_success "git-push ($PROTOCOL)" '
|
||||||
|
git -C workbench push origin \
|
||||||
|
$B:refs/heads/master \
|
||||||
|
HEAD:refs/heads/next \
|
||||||
|
>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: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
<OID-A>..<OID-B> <COMMIT-B> -> master
|
||||||
|
* [new branch] HEAD -> next
|
||||||
|
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/next
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
# Refs of upstream : master(B) next(A)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
# git-push --atomic: master(A) next(B)
|
||||||
|
test_expect_success "git-push --atomic ($PROTOCOL)" '
|
||||||
|
test_must_fail git -C workbench push --atomic origin \
|
||||||
|
master \
|
||||||
|
$B:refs/heads/next \
|
||||||
|
>out 2>&1 &&
|
||||||
|
make_user_friendly_and_stable_output <out |
|
||||||
|
sed -n \
|
||||||
|
-e "/^To / { s/ */ /g; p; }" \
|
||||||
|
-e "/^ ! / { s/ */ /g; p; }" \
|
||||||
|
>actual &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
! [rejected] master -> master (non-fast-forward)
|
||||||
|
! [rejected] <COMMIT-B> -> next (atomic push failed)
|
||||||
|
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/next
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
# Refs of upstream : master(B) next(A)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
# git-push : master(A) next(B)
|
||||||
|
test_expect_success "non-fast-forward git-push ($PROTOCOL)" '
|
||||||
|
test_must_fail git \
|
||||||
|
-C workbench \
|
||||||
|
-c advice.pushUpdateRejected=false \
|
||||||
|
push origin \
|
||||||
|
master \
|
||||||
|
$B:refs/heads/next \
|
||||||
|
>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/next
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/next
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
<OID-A>..<OID-B> <COMMIT-B> -> next
|
||||||
|
! [rejected] master -> master (non-fast-forward)
|
||||||
|
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-B> refs/heads/next
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
# Refs of upstream : master(B) next(B)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
# git-push -f : master(A) NULL tags/v123 refs/review/master/topic(A) a/b/c(A)
|
||||||
|
test_expect_success "git-push -f ($PROTOCOL)" '
|
||||||
|
git -C workbench push -f origin \
|
||||||
|
refs/tags/v123 \
|
||||||
|
:refs/heads/next \
|
||||||
|
master \
|
||||||
|
master:refs/review/master/topic \
|
||||||
|
HEAD:refs/heads/a/b/c \
|
||||||
|
>out 2>&1 &&
|
||||||
|
make_user_friendly_and_stable_output <out >actual &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
remote: # pre-receive hook
|
||||||
|
remote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
|
||||||
|
remote: pre-receive< <COMMIT-B> <ZERO-OID> refs/heads/next
|
||||||
|
remote: pre-receive< <ZERO-OID> <TAG-v123> refs/tags/v123
|
||||||
|
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic
|
||||||
|
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
|
||||||
|
remote: post-receive< <COMMIT-B> <ZERO-OID> refs/heads/next
|
||||||
|
remote: post-receive< <ZERO-OID> <TAG-v123> refs/tags/v123
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
+ <OID-B>...<OID-A> master -> master (forced update)
|
||||||
|
- [deleted] next
|
||||||
|
* [new tag] v123 -> v123
|
||||||
|
* [new reference] master -> refs/review/master/topic
|
||||||
|
* [new branch] HEAD -> a/b/c
|
||||||
|
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/a/b/c
|
||||||
|
<COMMIT-A> refs/heads/master
|
||||||
|
<COMMIT-A> refs/review/master/topic
|
||||||
|
<TAG-v123> refs/tags/v123
|
||||||
|
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 ($PROTOCOL)" '
|
||||||
|
(
|
||||||
|
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
|
||||||
|
)
|
||||||
|
'
|
147
t/t5411/test-0001-standard-git-push--porcelain.sh
Normal file
147
t/t5411/test-0001-standard-git-push--porcelain.sh
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
# Refs of upstream : master(A)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
# git-push : master(B) next(A)
|
||||||
|
test_expect_success "git-push ($PROTOCOL/porcelain)" '
|
||||||
|
git -C workbench push --porcelain origin \
|
||||||
|
$B:refs/heads/master \
|
||||||
|
HEAD:refs/heads/next \
|
||||||
|
>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: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
<COMMIT-B>:refs/heads/master <OID-A>..<OID-B>
|
||||||
|
* HEAD:refs/heads/next [new branch]
|
||||||
|
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/next
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
# Refs of upstream : master(B) next(A)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
# git-push --atomic: master(A) next(B)
|
||||||
|
test_expect_success "git-push --atomic ($PROTOCOL/porcelain)" '
|
||||||
|
test_must_fail git -C workbench push --atomic --porcelain origin \
|
||||||
|
master \
|
||||||
|
$B:refs/heads/next \
|
||||||
|
>out 2>&1 &&
|
||||||
|
make_user_friendly_and_stable_output <out |
|
||||||
|
sed -n \
|
||||||
|
-e "s/^# GETTEXT POISON #//" \
|
||||||
|
-e "/^To / { s/ */ /g; p; }" \
|
||||||
|
-e "/^! / { s/ */ /g; p; }" \
|
||||||
|
>actual &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
! refs/heads/master:refs/heads/master [rejected] (non-fast-forward)
|
||||||
|
! <COMMIT-B>:refs/heads/next [rejected] (atomic push failed)
|
||||||
|
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/next
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
# Refs of upstream : master(B) next(A)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
# git-push : master(A) next(B)
|
||||||
|
test_expect_success "non-fast-forward git-push ($PROTOCOL/porcelain)" '
|
||||||
|
test_must_fail git \
|
||||||
|
-C workbench \
|
||||||
|
-c advice.pushUpdateRejected=false \
|
||||||
|
push --porcelain origin \
|
||||||
|
master \
|
||||||
|
$B:refs/heads/next \
|
||||||
|
>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/next
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/next
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
<COMMIT-B>:refs/heads/next <OID-A>..<OID-B>
|
||||||
|
! refs/heads/master:refs/heads/master [rejected] (non-fast-forward)
|
||||||
|
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-B> refs/heads/next
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
# Refs of upstream : master(B) next(B)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
# git-push -f : master(A) NULL tags/v123 refs/review/master/topic(A) a/b/c(A)
|
||||||
|
test_expect_success "git-push -f ($PROTOCOL/porcelain)" '
|
||||||
|
git -C workbench push --porcelain -f origin \
|
||||||
|
refs/tags/v123 \
|
||||||
|
:refs/heads/next \
|
||||||
|
master \
|
||||||
|
master:refs/review/master/topic \
|
||||||
|
HEAD:refs/heads/a/b/c \
|
||||||
|
>out 2>&1 &&
|
||||||
|
make_user_friendly_and_stable_output <out >actual &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
remote: # pre-receive hook
|
||||||
|
remote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
|
||||||
|
remote: pre-receive< <COMMIT-B> <ZERO-OID> refs/heads/next
|
||||||
|
remote: pre-receive< <ZERO-OID> <TAG-v123> refs/tags/v123
|
||||||
|
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic
|
||||||
|
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
|
||||||
|
remote: post-receive< <COMMIT-B> <ZERO-OID> refs/heads/next
|
||||||
|
remote: post-receive< <ZERO-OID> <TAG-v123> refs/tags/v123
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
+ refs/heads/master:refs/heads/master <OID-B>...<OID-A> (forced update)
|
||||||
|
- :refs/heads/next [deleted]
|
||||||
|
* refs/tags/v123:refs/tags/v123 [new tag]
|
||||||
|
* refs/heads/master:refs/review/master/topic [new reference]
|
||||||
|
* HEAD:refs/heads/a/b/c [new branch]
|
||||||
|
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/a/b/c
|
||||||
|
<COMMIT-A> refs/heads/master
|
||||||
|
<COMMIT-A> refs/review/master/topic
|
||||||
|
<TAG-v123> refs/tags/v123
|
||||||
|
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 ($PROTOCOL/porcelain)" '
|
||||||
|
(
|
||||||
|
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
|
||||||
|
)
|
||||||
|
'
|
33
t/t5411/test-0002-pre-receive-declined.sh
Normal file
33
t/t5411/test-0002-pre-receive-declined.sh
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
test_expect_success "setup pre-receive hook ($PROTOCOL)" '
|
||||||
|
mv "$upstream/hooks/pre-receive" "$upstream/hooks/pre-receive.ok" &&
|
||||||
|
write_script "$upstream/hooks/pre-receive" <<-EOF
|
||||||
|
exit 1
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
|
||||||
|
# Refs of upstream : master(A)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
# git-push : master(B) next(A)
|
||||||
|
test_expect_success "git-push is declined ($PROTOCOL)" '
|
||||||
|
test_must_fail git -C workbench push origin \
|
||||||
|
$B:refs/heads/master \
|
||||||
|
HEAD:refs/heads/next \
|
||||||
|
>out 2>&1 &&
|
||||||
|
make_user_friendly_and_stable_output <out >actual &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
! [remote rejected] <COMMIT-B> -> master (pre-receive hook declined)
|
||||||
|
! [remote rejected] HEAD -> next (pre-receive hook declined)
|
||||||
|
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 "cleanup ($PROTOCOL)" '
|
||||||
|
mv "$upstream/hooks/pre-receive.ok" "$upstream/hooks/pre-receive"
|
||||||
|
'
|
34
t/t5411/test-0003-pre-receive-declined--porcelain.sh
Normal file
34
t/t5411/test-0003-pre-receive-declined--porcelain.sh
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
test_expect_success "setup pre-receive hook ($PROTOCOL/porcelain)" '
|
||||||
|
mv "$upstream/hooks/pre-receive" "$upstream/hooks/pre-receive.ok" &&
|
||||||
|
write_script "$upstream/hooks/pre-receive" <<-EOF
|
||||||
|
exit 1
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
|
||||||
|
# Refs of upstream : master(A)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
# git-push : master(B) next(A)
|
||||||
|
test_expect_success "git-push is declined ($PROTOCOL/porcelain)" '
|
||||||
|
test_must_fail git -C workbench push --porcelain origin \
|
||||||
|
$B:refs/heads/master \
|
||||||
|
HEAD:refs/heads/next \
|
||||||
|
>out 2>&1 &&
|
||||||
|
make_user_friendly_and_stable_output <out >actual &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
! <COMMIT-B>:refs/heads/master [remote rejected] (pre-receive hook declined)
|
||||||
|
! HEAD:refs/heads/next [remote rejected] (pre-receive hook declined)
|
||||||
|
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 "cleanup ($PROTOCOL/porcelain)" '
|
||||||
|
mv "$upstream/hooks/pre-receive.ok" "$upstream/hooks/pre-receive"
|
||||||
|
'
|
7
t/t5411/test-0010-proc-receive-settings.sh
Normal file
7
t/t5411/test-0010-proc-receive-settings.sh
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
test_expect_success "add two receive.procReceiveRefs settings" '
|
||||||
|
(
|
||||||
|
cd "$upstream" &&
|
||||||
|
git config --add receive.procReceiveRefs refs/for &&
|
||||||
|
git config --add receive.procReceiveRefs refs/review/
|
||||||
|
)
|
||||||
|
'
|
64
t/t5411/test-0011-no-hook-error.sh
Normal file
64
t/t5411/test-0011-no-hook-error.sh
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# 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 ($PROTOCOL)" '
|
||||||
|
test_must_fail git -C workbench push 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>
|
||||||
|
* [new branch] HEAD -> next
|
||||||
|
! [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
|
||||||
|
<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
|
||||||
|
'
|
||||||
|
|
||||||
|
# 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 ($PROTOCOL)" '
|
||||||
|
test_must_fail git -C workbench push --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>
|
||||||
|
! [remote rejected] <COMMIT-B> -> master (fail to run proc-receive hook)
|
||||||
|
! [remote rejected] HEAD -> next (fail to run proc-receive hook)
|
||||||
|
! [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
|
||||||
|
'
|
66
t/t5411/test-0012-no-hook-error--porcelain.sh
Normal file
66
t/t5411/test-0012-no-hook-error--porcelain.sh
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# 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 ($PROTOCOL/porcelain)" '
|
||||||
|
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/porcelain)" '
|
||||||
|
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, all failed for atomic push ($PROTOCOL/porcelain)" '
|
||||||
|
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
|
||||||
|
'
|
217
t/t5411/test-0013-bad-protocol.sh
Normal file
217
t/t5411/test-0013-bad-protocol.sh
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
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
|
||||||
|
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 (unknown 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 &&
|
||||||
|
|
||||||
|
# Check status report for git-push
|
||||||
|
sed -n \
|
||||||
|
-e "/^To / { p; n; p; }" \
|
||||||
|
<actual >actual-report &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
! [remote rejected] HEAD -> refs/for/master/topic (fail to run proc-receive hook)
|
||||||
|
EOF
|
||||||
|
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 &&
|
||||||
|
<COMMIT-A> refs/heads/master
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
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 &&
|
||||||
|
|
||||||
|
grep "remote: fatal: protocol error: expected \"old new ref\", got \"<ZERO-OID> <COMMIT-A> refs/for/master/topic\"" 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
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
|
||||||
|
# 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, $PROTOCOL)" '
|
||||||
|
test_must_fail git -C workbench push 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: # post-receive hook
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
* [new branch] HEAD -> next
|
||||||
|
! [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
|
||||||
|
<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 (no ref, $PROTOCOL)" '
|
||||||
|
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||||
|
printf >&2 "# proc-receive hook\n"
|
||||||
|
test-tool proc-receive -v \
|
||||||
|
-r "ok"
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
|
||||||
|
# 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, $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> ok
|
||||||
|
remote: error: proc-receive reported incomplete status line: "ok"
|
||||||
|
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 (unknown status, $PROTOCOL)" '
|
||||||
|
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||||
|
printf >&2 "# proc-receive hook\n"
|
||||||
|
test-tool proc-receive -v \
|
||||||
|
-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: bad protocol (unknown status, $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> xx refs/for/master/topic
|
||||||
|
remote: error: proc-receive reported bad status "xx" on ref "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
|
||||||
|
'
|
160
t/t5411/test-0014-bad-protocol--porcelain.sh
Normal file
160
t/t5411/test-0014-bad-protocol--porcelain.sh
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
test_expect_success "setup proc-receive hook (unknown version, $PROTOCOL/porcelain)" '
|
||||||
|
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||||
|
printf >&2 "# proc-receive hook\n"
|
||||||
|
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(A)
|
||||||
|
test_expect_success "proc-receive: bad protocol (unknown version, $PROTOCOL/porcelain)" '
|
||||||
|
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 &&
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
! HEAD:refs/for/master/topic [remote rejected] (fail to run proc-receive hook)
|
||||||
|
Done
|
||||||
|
EOF
|
||||||
|
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 &&
|
||||||
|
<COMMIT-A> refs/heads/master
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (no report, $PROTOCOL/porcelain)" '
|
||||||
|
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||||
|
printf >&2 "# proc-receive hook\n"
|
||||||
|
test-tool proc-receive -v
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
|
||||||
|
# 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, $PROTOCOL/porcelain)" '
|
||||||
|
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: # 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] (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
|
||||||
|
'
|
||||||
|
|
||||||
|
# Refs of upstream : master(A) next(A)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
test_expect_success "cleanup ($PROTOCOL/porcelain)" '
|
||||||
|
git -C "$upstream" update-ref -d refs/heads/next
|
||||||
|
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (no ref, $PROTOCOL/porcelain)" '
|
||||||
|
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||||
|
printf >&2 "# proc-receive hook\n"
|
||||||
|
test-tool proc-receive -v \
|
||||||
|
-r "ok"
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
|
||||||
|
# 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, $PROTOCOL/porcelain)" '
|
||||||
|
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
|
||||||
|
remote: error: proc-receive reported incomplete status line: "ok"
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
! 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
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (unknown status, $PROTOCOL/porcelain)" '
|
||||||
|
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||||
|
printf >&2 "# proc-receive hook\n"
|
||||||
|
test-tool proc-receive -v \
|
||||||
|
-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: bad protocol (unknown status, $PROTOCOL/porcelain)" '
|
||||||
|
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> xx refs/for/master/topic
|
||||||
|
remote: error: proc-receive reported bad status "xx" on ref "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 &&
|
||||||
|
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
|
||||||
|
'
|
67
t/t5411/test-0020-report-ng.sh
Normal file
67
t/t5411/test-0020-report-ng.sh
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
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, $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
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
! [remote rejected] HEAD -> refs/for/master/topic (failed)
|
||||||
|
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, $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
|
||||||
|
'
|
69
t/t5411/test-0021-report-ng--porcelain.sh
Normal file
69
t/t5411/test-0021-report-ng--porcelain.sh
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
test_expect_success "setup proc-receive hook (ng, no message, $PROTOCOL/porcelain)" '
|
||||||
|
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, $PROTOCOL/porcelain)" '
|
||||||
|
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/porcelain)" '
|
||||||
|
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/porcelain)" '
|
||||||
|
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
|
||||||
|
'
|
45
t/t5411/test-0022-report-unexpect-ref.sh
Normal file
45
t/t5411/test-0022-report-unexpect-ref.sh
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
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
|
||||||
|
'
|
46
t/t5411/test-0023-report-unexpect-ref--porcelain.sh
Normal file
46
t/t5411/test-0023-report-unexpect-ref--porcelain.sh
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL/porcelain)" '
|
||||||
|
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/porcelain)" '
|
||||||
|
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/porcelain)" '
|
||||||
|
git -C "$upstream" update-ref refs/heads/master $A
|
||||||
|
'
|
34
t/t5411/test-0024-report-unknown-ref.sh
Normal file
34
t/t5411/test-0024-report-unknown-ref.sh
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
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
|
||||||
|
'
|
35
t/t5411/test-0025-report-unknown-ref--porcelain.sh
Normal file
35
t/t5411/test-0025-report-unknown-ref--porcelain.sh
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL/porcelain)" '
|
||||||
|
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/porcelain)" '
|
||||||
|
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
|
||||||
|
'
|
79
t/t5411/test-0026-push-options.sh
Normal file
79
t/t5411/test-0026-push-options.sh
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
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 &&
|
||||||
|
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
|
||||||
|
'
|
82
t/t5411/test-0027-push-options--porcelain.sh
Normal file
82
t/t5411/test-0027-push-options--porcelain.sh
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
test_expect_success "setup proc-receive hook and disable push-options ($PROTOCOL/porcelain)" '
|
||||||
|
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/porcelain)" '
|
||||||
|
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/porcelain)" '
|
||||||
|
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/porcelain)" '
|
||||||
|
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/porcelain)" '
|
||||||
|
git -C "$upstream" update-ref -d refs/heads/next
|
||||||
|
'
|
35
t/t5411/test-0030-report-ok.sh
Normal file
35
t/t5411/test-0030-report-ok.sh
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
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
|
||||||
|
'
|
36
t/t5411/test-0031-report-ok--porcelain.sh
Normal file
36
t/t5411/test-0031-report-ok--porcelain.sh
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
test_expect_success "setup proc-receive hook (ok, $PROTOCOL/porcelain)" '
|
||||||
|
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/porcelain)" '
|
||||||
|
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
|
||||||
|
'
|
256
t/t5411/test-0032-report-with-options.sh
Normal file
256
t/t5411/test-0032-report-with-options.sh
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
test_expect_success "setup proc-receive hook (option without matching ok, $PROTOCOL)" '
|
||||||
|
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||||
|
printf >&2 "# proc-receive hook\n"
|
||||||
|
test-tool proc-receive -v \
|
||||||
|
-r "option refname refs/pull/123/head" \
|
||||||
|
-r "option 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 option without matching ok ($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> option refname refs/pull/123/head
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-B>
|
||||||
|
remote: error: proc-receive reported "option" without a matching "ok/ng" directive
|
||||||
|
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 (option refname, $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 "option refname 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 option refname ($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> option refname refs/pull/123/head
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
* [new reference] HEAD -> refs/pull/123/head
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (option refname and forced-update, $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 "option refname refs/pull/123/head" \
|
||||||
|
-r "option 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 option refname and 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> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/pull/123/head
|
||||||
|
remote: proc-receive> option forced-update
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
* [new reference] HEAD -> refs/pull/123/head
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (option refname and old-oid, $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 "option refname refs/pull/123/head" \
|
||||||
|
-r "option 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 option refname and old-oid ($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> option refname refs/pull/123/head
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-B>
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/123/head
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
<OID-B>..<OID-A> HEAD -> refs/pull/123/head
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (option old-oid, $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 "option 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 option old-oid ($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> option old-oid <COMMIT-B>
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/for/master/topic
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
<OID-B>..<OID-A> HEAD -> refs/for/master/topic
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (option old-oid and new-oid, $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 "option old-oid $A" \
|
||||||
|
-r "option 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 option old-oid and new-oid ($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> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-B>
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
<OID-A>..<OID-B> HEAD -> refs/for/master/topic
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (report with multiple rewrites, $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 "ok refs/for/next/topic" \
|
||||||
|
-r "option refname refs/pull/123/head" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option refname refs/pull/124/head" \
|
||||||
|
-r "option old-oid $B" \
|
||||||
|
-r "option forced-update" \
|
||||||
|
-r "option 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: report with multiple rewrites ($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> ok refs/for/next/topic
|
||||||
|
remote: proc-receive> option refname refs/pull/123/head
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/pull/124/head
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-B>
|
||||||
|
remote: proc-receive> option forced-update
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-A>
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
|
||||||
|
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/124/head
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
* [new reference] HEAD -> refs/pull/123/head
|
||||||
|
* [new reference] HEAD -> refs/for/a/b/c/topic
|
||||||
|
+ <OID-B>...<OID-A> HEAD -> refs/pull/124/head (forced update)
|
||||||
|
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
|
||||||
|
'
|
265
t/t5411/test-0033-report-with-options--porcelain.sh
Normal file
265
t/t5411/test-0033-report-with-options--porcelain.sh
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
test_expect_success "setup proc-receive hook (option without matching ok, $PROTOCOL/porcelain)" '
|
||||||
|
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||||
|
printf >&2 "# proc-receive hook\n"
|
||||||
|
test-tool proc-receive -v \
|
||||||
|
-r "option refname refs/pull/123/head" \
|
||||||
|
-r "option 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 option without matching ok ($PROTOCOL/porcelain)" '
|
||||||
|
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> option refname refs/pull/123/head
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-B>
|
||||||
|
remote: error: proc-receive reported "option" without a matching "ok/ng" directive
|
||||||
|
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 (option refname, $PROTOCOL/porcelain)" '
|
||||||
|
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 "option refname 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 option refname ($PROTOCOL/porcelain)" '
|
||||||
|
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> option refname refs/pull/123/head
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
* HEAD:refs/pull/123/head [new reference]
|
||||||
|
Done
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (option refname and forced-update, $PROTOCOL/porcelain)" '
|
||||||
|
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 "option refname refs/pull/123/head" \
|
||||||
|
-r "option 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 option refname and forced-update ($PROTOCOL/porcelain)" '
|
||||||
|
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> option refname refs/pull/123/head
|
||||||
|
remote: proc-receive> option forced-update
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
* HEAD:refs/pull/123/head [new reference]
|
||||||
|
Done
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (option refname and old-oid, $PROTOCOL/porcelain)" '
|
||||||
|
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 "option refname refs/pull/123/head" \
|
||||||
|
-r "option 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 option refname and old-oid ($PROTOCOL/porcelain)" '
|
||||||
|
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> option refname refs/pull/123/head
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-B>
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/123/head
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
HEAD:refs/pull/123/head <OID-B>..<OID-A>
|
||||||
|
Done
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (option old-oid, $PROTOCOL/porcelain)" '
|
||||||
|
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 "option 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 option old-oid ($PROTOCOL/porcelain)" '
|
||||||
|
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> option old-oid <COMMIT-B>
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/for/master/topic
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
HEAD:refs/for/master/topic <OID-B>..<OID-A>
|
||||||
|
Done
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (option old-oid and new-oid, $PROTOCOL/porcelain)" '
|
||||||
|
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 "option old-oid $A" \
|
||||||
|
-r "option 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 option old-oid and new-oid ($PROTOCOL/porcelain)" '
|
||||||
|
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> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-B>
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
HEAD:refs/for/master/topic <OID-A>..<OID-B>
|
||||||
|
Done
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (report with multiple rewrites, $PROTOCOL/porcelain)" '
|
||||||
|
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/for/next/topic" \
|
||||||
|
-r "option refname refs/pull/123/head" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option refname refs/pull/124/head" \
|
||||||
|
-r "option old-oid $B" \
|
||||||
|
-r "option forced-update" \
|
||||||
|
-r "option 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: report with multiple rewrites ($PROTOCOL/porcelain)" '
|
||||||
|
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> ok refs/for/next/topic
|
||||||
|
remote: proc-receive> option refname refs/pull/123/head
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/pull/124/head
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-B>
|
||||||
|
remote: proc-receive> option forced-update
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-A>
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
|
||||||
|
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/124/head
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
* HEAD:refs/pull/123/head [new reference]
|
||||||
|
* HEAD:refs/for/a/b/c/topic [new reference]
|
||||||
|
+ 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-A> refs/heads/master
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
44
t/t5411/test-0034-report-ft.sh
Normal file
44
t/t5411/test-0034-report-ft.sh
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
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 "ok refs/for/master/topic" \
|
||||||
|
-r "option fall-through"
|
||||||
|
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> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option fall-through
|
||||||
|
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
|
||||||
|
'
|
45
t/t5411/test-0035-report-ft--porcelain.sh
Normal file
45
t/t5411/test-0035-report-ft--porcelain.sh
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
test_expect_success "setup proc-receive hook (fall-through, $PROTOCOL/porcelain)" '
|
||||||
|
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 "option fall-through"
|
||||||
|
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/porcelain)" '
|
||||||
|
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> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option fall-through
|
||||||
|
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/porcelain)" '
|
||||||
|
git -C "$upstream" update-ref -d refs/for/master/topic
|
||||||
|
'
|
227
t/t5411/test-0036-report-multi-rewrite-for-one-ref.sh
Normal file
227
t/t5411/test-0036-report-multi-rewrite-for-one-ref.sh
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
test_expect_success "setup git config for remote-tracking of special refs" '
|
||||||
|
(
|
||||||
|
cd workbench &&
|
||||||
|
if ! git config --get-all remote.origin.fetch | grep refs/for/
|
||||||
|
then
|
||||||
|
git config --add remote.origin.fetch \
|
||||||
|
"+refs/for/*:refs/t/for/*" &&
|
||||||
|
git config --add remote.origin.fetch \
|
||||||
|
"+refs/pull/*:refs/t/pull/*" &&
|
||||||
|
git config --add remote.origin.fetch \
|
||||||
|
"+refs/changes/*:refs/t/changes/*"
|
||||||
|
fi
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 1st rewrite, $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 "option old-oid $A" \
|
||||||
|
-r "option new-oid $B" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option refname refs/changes/24/124/1" \
|
||||||
|
-r "option old-oid $ZERO_OID" \
|
||||||
|
-r "option new-oid $A" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option refname refs/changes/25/125/1" \
|
||||||
|
-r "option old-oid $A" \
|
||||||
|
-r "option 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: multiple rewrite for one ref, no refname for the 1st rewrite ($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> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-B>
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/changes/24/124/1
|
||||||
|
remote: proc-receive> option old-oid <ZERO-OID>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/changes/25/125/1
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-B>
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/24/124/1
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/changes/25/125/1
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
<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 &&
|
||||||
|
make_user_friendly_and_stable_output <out >actual &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
<COMMIT-A> refs/heads/master
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "proc-receive: check remote-tracking #1 ($PROTOCOL)" '
|
||||||
|
git -C workbench show-ref |
|
||||||
|
grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
|
||||||
|
make_user_friendly_and_stable_output <out >actual &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
<COMMIT-A> refs/t/changes/24/124/1
|
||||||
|
<COMMIT-B> refs/t/changes/25/125/1
|
||||||
|
<COMMIT-B> refs/t/for/master/topic
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual &&
|
||||||
|
git -C workbench update-ref -d refs/t/for/master/topic &&
|
||||||
|
git -C workbench update-ref -d refs/t/changes/24/124/1 &&
|
||||||
|
git -C workbench update-ref -d refs/t/changes/25/125/1
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 2nd rewrite, $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 "option refname refs/changes/24/124/1" \
|
||||||
|
-r "option old-oid $ZERO_OID" \
|
||||||
|
-r "option new-oid $A" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option old-oid $A" \
|
||||||
|
-r "option new-oid $B" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option refname refs/changes/25/125/1" \
|
||||||
|
-r "option old-oid $B" \
|
||||||
|
-r "option new-oid $A" \
|
||||||
|
-r "option forced-update"
|
||||||
|
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: multiple rewrites for one ref, no refname for the 2nd rewrite ($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> option refname refs/changes/24/124/1
|
||||||
|
remote: proc-receive> option old-oid <ZERO-OID>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-B>
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/changes/25/125/1
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-B>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option forced-update
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/24/124/1
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||||
|
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/changes/25/125/1
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
* [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 &&
|
||||||
|
make_user_friendly_and_stable_output <out >actual &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
<COMMIT-A> refs/heads/master
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "proc-receive: check remote-tracking #2 ($PROTOCOL)" '
|
||||||
|
git -C workbench show-ref |
|
||||||
|
grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
|
||||||
|
make_user_friendly_and_stable_output <out >actual &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
<COMMIT-A> refs/t/changes/24/124/1
|
||||||
|
<COMMIT-A> refs/t/changes/25/125/1
|
||||||
|
<COMMIT-B> refs/t/for/master/topic
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual &&
|
||||||
|
git -C workbench update-ref -d refs/t/for/master/topic &&
|
||||||
|
git -C workbench update-ref -d refs/t/changes/24/124/1 &&
|
||||||
|
git -C workbench update-ref -d refs/t/changes/25/125/1
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "setup proc-receive hook (multiple rewrites for one 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 "option refname refs/changes/23/123/1" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option refname refs/changes/24/124/2" \
|
||||||
|
-r "option old-oid $A" \
|
||||||
|
-r "option 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: multiple rewrites for one 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> option refname refs/changes/23/123/1
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/changes/24/124/2
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-B>
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/23/123/1
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/changes/24/124/2
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
* [new reference] HEAD -> refs/changes/23/123/1
|
||||||
|
<OID-A>..<OID-B> HEAD -> refs/changes/24/124/2
|
||||||
|
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 "proc-receive: check remote-tracking #3 ($PROTOCOL)" '
|
||||||
|
git -C workbench show-ref |
|
||||||
|
grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
|
||||||
|
make_user_friendly_and_stable_output <out >actual &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
<COMMIT-A> refs/t/changes/23/123/1
|
||||||
|
<COMMIT-B> refs/t/changes/24/124/2
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual &&
|
||||||
|
git -C workbench update-ref -d refs/t/changes/24/124/1 &&
|
||||||
|
git -C workbench update-ref -d refs/t/changes/25/125/2
|
||||||
|
'
|
172
t/t5411/test-0037-report-multi-rewrite-for-one-ref--porcelain.sh
Normal file
172
t/t5411/test-0037-report-multi-rewrite-for-one-ref--porcelain.sh
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 1st rewrite, $PROTOCOL/porcelain)" '
|
||||||
|
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 "option old-oid $A" \
|
||||||
|
-r "option new-oid $B" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option refname refs/changes/24/124/1" \
|
||||||
|
-r "option old-oid $ZERO_OID" \
|
||||||
|
-r "option new-oid $A" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option refname refs/changes/25/125/1" \
|
||||||
|
-r "option old-oid $A" \
|
||||||
|
-r "option 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: multiple rewrite for one ref, no refname for the 1st rewrite ($PROTOCOL/porcelain)" '
|
||||||
|
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> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-B>
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/changes/24/124/1
|
||||||
|
remote: proc-receive> option old-oid <ZERO-OID>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/changes/25/125/1
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-B>
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/24/124/1
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/changes/25/125/1
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
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 &&
|
||||||
|
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 (multiple rewrites for one ref, no refname for the 2nd rewrite, $PROTOCOL/porcelain)" '
|
||||||
|
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 "option refname refs/changes/24/124/1" \
|
||||||
|
-r "option old-oid $ZERO_OID" \
|
||||||
|
-r "option new-oid $A" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option old-oid $A" \
|
||||||
|
-r "option new-oid $B" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option refname refs/changes/25/125/1" \
|
||||||
|
-r "option old-oid $B" \
|
||||||
|
-r "option new-oid $A" \
|
||||||
|
-r "option forced-update"
|
||||||
|
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: multiple rewrites for one ref, no refname for the 2nd rewrite ($PROTOCOL/porcelain)" '
|
||||||
|
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> option refname refs/changes/24/124/1
|
||||||
|
remote: proc-receive> option old-oid <ZERO-OID>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-B>
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/changes/25/125/1
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-B>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option forced-update
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/24/124/1
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||||
|
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/changes/25/125/1
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
* 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 &&
|
||||||
|
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 (multiple rewrites for one ref, $PROTOCOL/porcelain)" '
|
||||||
|
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 "option refname refs/changes/23/123/1" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option refname refs/changes/24/124/2" \
|
||||||
|
-r "option old-oid $A" \
|
||||||
|
-r "option 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: multiple rewrites for one ref ($PROTOCOL/porcelain)" '
|
||||||
|
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> option refname refs/changes/23/123/1
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/changes/24/124/2
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-B>
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/23/123/1
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/changes/24/124/2
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
* HEAD:refs/changes/23/123/1 [new reference]
|
||||||
|
HEAD:refs/changes/24/124/2 <OID-A>..<OID-B>
|
||||||
|
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
|
||||||
|
'
|
89
t/t5411/test-0038-report-mixed-refs.sh
Normal file
89
t/t5411/test-0038-report-mixed-refs.sh
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
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/topic2" \
|
||||||
|
-r "ng refs/for/next/topic1 fail to call Web API" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option refname refs/for/master/topic" \
|
||||||
|
-r "option old-oid $A" \
|
||||||
|
-r "option 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 ($PROTOCOL)" '
|
||||||
|
test_must_fail git -C workbench push origin \
|
||||||
|
$B:refs/heads/master \
|
||||||
|
HEAD:refs/heads/bar \
|
||||||
|
HEAD:refs/heads/baz \
|
||||||
|
HEAD:refs/for/next/topic2 \
|
||||||
|
HEAD:refs/for/next/topic1 \
|
||||||
|
HEAD:refs/heads/foo \
|
||||||
|
HEAD:refs/for/master/topic \
|
||||||
|
HEAD:refs/for/next/topic3 \
|
||||||
|
>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/topic2
|
||||||
|
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic1
|
||||||
|
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo
|
||||||
|
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||||
|
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic3
|
||||||
|
remote: # proc-receive hook
|
||||||
|
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic2
|
||||||
|
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic1
|
||||||
|
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||||
|
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic3
|
||||||
|
remote: proc-receive> ok refs/for/next/topic2
|
||||||
|
remote: proc-receive> ng refs/for/next/topic1 fail to call Web API
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/for/master/topic
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option 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/topic2
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
<OID-A>..<OID-B> <COMMIT-B> -> master
|
||||||
|
* [new branch] HEAD -> bar
|
||||||
|
* [new branch] HEAD -> baz
|
||||||
|
* [new reference] HEAD -> refs/for/next/topic2
|
||||||
|
* [new branch] HEAD -> foo
|
||||||
|
<OID-A>..<OID-B> HEAD -> refs/for/master/topic
|
||||||
|
! [remote rejected] HEAD -> refs/for/next/topic1 (fail to call Web API)
|
||||||
|
! [remote rejected] HEAD -> refs/for/next/topic3 (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/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
|
||||||
|
)
|
||||||
|
'
|
91
t/t5411/test-0039-report-mixed-refs--porcelain.sh
Normal file
91
t/t5411/test-0039-report-mixed-refs--porcelain.sh
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
test_expect_success "setup proc-receive hook ($PROTOCOL/porcelain)" '
|
||||||
|
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||||
|
printf >&2 "# proc-receive hook\n"
|
||||||
|
test-tool proc-receive -v \
|
||||||
|
-r "ok refs/for/next/topic2" \
|
||||||
|
-r "ng refs/for/next/topic1 fail to call Web API" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option refname refs/for/master/topic" \
|
||||||
|
-r "option old-oid $A" \
|
||||||
|
-r "option 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 ($PROTOCOL/porcelain)" '
|
||||||
|
test_must_fail git -C workbench push --porcelain origin \
|
||||||
|
$B:refs/heads/master \
|
||||||
|
HEAD:refs/heads/bar \
|
||||||
|
HEAD:refs/heads/baz \
|
||||||
|
HEAD:refs/for/next/topic2 \
|
||||||
|
HEAD:refs/for/next/topic1 \
|
||||||
|
HEAD:refs/heads/foo \
|
||||||
|
HEAD:refs/for/master/topic \
|
||||||
|
HEAD:refs/for/next/topic3 \
|
||||||
|
>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/topic2
|
||||||
|
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic1
|
||||||
|
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo
|
||||||
|
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||||
|
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic3
|
||||||
|
remote: # proc-receive hook
|
||||||
|
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic2
|
||||||
|
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic1
|
||||||
|
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||||
|
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic3
|
||||||
|
remote: proc-receive> ok refs/for/next/topic2
|
||||||
|
remote: proc-receive> ng refs/for/next/topic1 fail to call Web API
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/for/master/topic
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option 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/topic2
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> 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/topic2 [new reference]
|
||||||
|
* HEAD:refs/heads/foo [new branch]
|
||||||
|
HEAD:refs/for/master/topic <OID-A>..<OID-B>
|
||||||
|
! HEAD:refs/for/next/topic1 [remote rejected] (fail to call Web API)
|
||||||
|
! HEAD:refs/for/next/topic3 [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/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/porcelain)" '
|
||||||
|
(
|
||||||
|
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
|
||||||
|
)
|
||||||
|
|
||||||
|
'
|
113
t/t5411/test-0040-process-all-refs.sh
Normal file
113
t/t5411/test-0040-process-all-refs.sh
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
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 "ok refs/heads/master" \
|
||||||
|
-r "option fall-through" \
|
||||||
|
-r "ok refs/heads/foo" \
|
||||||
|
-r "option fall-through" \
|
||||||
|
-r "ok refs/heads/bar" \
|
||||||
|
-r "option fall-through" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option refname refs/pull/123/head" \
|
||||||
|
-r "option old-oid $A" \
|
||||||
|
-r "option new-oid $B" \
|
||||||
|
-r "ok refs/for/next/topic" \
|
||||||
|
-r "option refname refs/pull/124/head" \
|
||||||
|
-r "option old-oid $B" \
|
||||||
|
-r "option new-oid $A" \
|
||||||
|
-r "option 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 ($PROTOCOL)" '
|
||||||
|
git -C workbench push -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> ok refs/heads/master
|
||||||
|
remote: proc-receive> option fall-through
|
||||||
|
remote: proc-receive> ok refs/heads/foo
|
||||||
|
remote: proc-receive> option fall-through
|
||||||
|
remote: proc-receive> ok refs/heads/bar
|
||||||
|
remote: proc-receive> option fall-through
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/pull/123/head
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-B>
|
||||||
|
remote: proc-receive> ok refs/for/next/topic
|
||||||
|
remote: proc-receive> option refname refs/pull/124/head
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-B>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option 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>
|
||||||
|
<OID-A>..<OID-B> <COMMIT-B> -> bar
|
||||||
|
- [deleted] foo
|
||||||
|
+ <OID-B>...<OID-A> HEAD -> master (forced update)
|
||||||
|
<OID-A>..<OID-B> HEAD -> refs/pull/123/head
|
||||||
|
+ <OID-B>...<OID-A> HEAD -> refs/pull/124/head (forced update)
|
||||||
|
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
|
||||||
|
)
|
||||||
|
'
|
114
t/t5411/test-0041-process-all-refs--porcelain.sh
Normal file
114
t/t5411/test-0041-process-all-refs--porcelain.sh
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
test_expect_success "config receive.procReceiveRefs = refs ($PROTOCOL/porcelain)" '
|
||||||
|
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/porcelain)" '
|
||||||
|
(
|
||||||
|
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/porcelain)" '
|
||||||
|
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||||
|
printf >&2 "# proc-receive hook\n"
|
||||||
|
test-tool proc-receive -v \
|
||||||
|
-r "ok refs/heads/master" \
|
||||||
|
-r "option fall-through" \
|
||||||
|
-r "ok refs/heads/foo" \
|
||||||
|
-r "option fall-through" \
|
||||||
|
-r "ok refs/heads/bar" \
|
||||||
|
-r "option fall-through" \
|
||||||
|
-r "ok refs/for/master/topic" \
|
||||||
|
-r "option refname refs/pull/123/head" \
|
||||||
|
-r "option old-oid $A" \
|
||||||
|
-r "option new-oid $B" \
|
||||||
|
-r "ok refs/for/next/topic" \
|
||||||
|
-r "option refname refs/pull/124/head" \
|
||||||
|
-r "option old-oid $B" \
|
||||||
|
-r "option new-oid $A" \
|
||||||
|
-r "option 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 ($PROTOCOL/porcelain)" '
|
||||||
|
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> ok refs/heads/master
|
||||||
|
remote: proc-receive> option fall-through
|
||||||
|
remote: proc-receive> ok refs/heads/foo
|
||||||
|
remote: proc-receive> option fall-through
|
||||||
|
remote: proc-receive> ok refs/heads/bar
|
||||||
|
remote: proc-receive> option fall-through
|
||||||
|
remote: proc-receive> ok refs/for/master/topic
|
||||||
|
remote: proc-receive> option refname refs/pull/123/head
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-B>
|
||||||
|
remote: proc-receive> ok refs/for/next/topic
|
||||||
|
remote: proc-receive> option refname refs/pull/124/head
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-B>
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option 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/porcelain)" '
|
||||||
|
(
|
||||||
|
cd "$upstream" &&
|
||||||
|
git update-ref -d refs/heads/bar &&
|
||||||
|
git update-ref -d refs/heads/baz
|
||||||
|
)
|
||||||
|
'
|
@ -1039,7 +1039,7 @@ test_force_fetch_tag "annotated tag" "-f -a -m'tag message'"
|
|||||||
test_expect_success 'push --porcelain' '
|
test_expect_success 'push --porcelain' '
|
||||||
mk_empty testrepo &&
|
mk_empty testrepo &&
|
||||||
echo >.git/foo "To testrepo" &&
|
echo >.git/foo "To testrepo" &&
|
||||||
echo >>.git/foo "* refs/heads/master:refs/remotes/origin/master [new branch]" &&
|
echo >>.git/foo "* refs/heads/master:refs/remotes/origin/master [new reference]" &&
|
||||||
echo >>.git/foo "Done" &&
|
echo >>.git/foo "Done" &&
|
||||||
git push >.git/bar --porcelain testrepo refs/heads/master:refs/remotes/origin/master &&
|
git push >.git/bar --porcelain testrepo refs/heads/master:refs/remotes/origin/master &&
|
||||||
(
|
(
|
||||||
|
@ -729,6 +729,49 @@ static int push_update_ref_status(struct strbuf *buf,
|
|||||||
{
|
{
|
||||||
char *refname, *msg;
|
char *refname, *msg;
|
||||||
int status, forced = 0;
|
int status, forced = 0;
|
||||||
|
static struct ref *hint = NULL;
|
||||||
|
static int new_options = 1;
|
||||||
|
|
||||||
|
if (starts_with(buf->buf, "option ")) {
|
||||||
|
struct ref_push_report_options *options;
|
||||||
|
struct object_id old_oid, new_oid;
|
||||||
|
const char *key, *val;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (!hint)
|
||||||
|
die(_("'option' without a matching 'ok/error' directive"));
|
||||||
|
options = hint->report.options;
|
||||||
|
while (options && options->next)
|
||||||
|
options = options->next;
|
||||||
|
if (new_options) {
|
||||||
|
if (!options) {
|
||||||
|
hint->report.options = xcalloc(1, sizeof(struct ref_push_report_options));
|
||||||
|
options = hint->report.options;
|
||||||
|
} else {
|
||||||
|
options->next = xcalloc(1, sizeof(struct ref_push_report_options));
|
||||||
|
options = options->next;
|
||||||
|
}
|
||||||
|
new_options = 0;
|
||||||
|
}
|
||||||
|
assert(options);
|
||||||
|
key = buf->buf + 7;
|
||||||
|
p = strchr(key, ' ');
|
||||||
|
if (p)
|
||||||
|
*p++ = '\0';
|
||||||
|
val = p;
|
||||||
|
if (!strcmp(key, "refname"))
|
||||||
|
options->ref_name = xstrdup_or_null(val);
|
||||||
|
else if (!strcmp(key, "old-oid") && val &&
|
||||||
|
!parse_oid_hex(val, &old_oid, &val))
|
||||||
|
options->old_oid = oiddup(&old_oid);
|
||||||
|
else if (!strcmp(key, "new-oid") && val &&
|
||||||
|
!parse_oid_hex(val, &new_oid, &val))
|
||||||
|
options->new_oid = oiddup(&new_oid);
|
||||||
|
else if (!strcmp(key, "forced-update"))
|
||||||
|
options->forced_update = 1;
|
||||||
|
/* Not update remote namespace again. */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (starts_with(buf->buf, "ok ")) {
|
if (starts_with(buf->buf, "ok ")) {
|
||||||
status = REF_STATUS_OK;
|
status = REF_STATUS_OK;
|
||||||
@ -791,8 +834,11 @@ static int push_update_ref_status(struct strbuf *buf,
|
|||||||
*ref = find_ref_by_name(remote_refs, refname);
|
*ref = find_ref_by_name(remote_refs, refname);
|
||||||
if (!*ref) {
|
if (!*ref) {
|
||||||
warning(_("helper reported unexpected status of %s"), refname);
|
warning(_("helper reported unexpected status of %s"), refname);
|
||||||
|
hint = NULL;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
hint = *ref;
|
||||||
|
new_options = 1;
|
||||||
|
|
||||||
if ((*ref)->status != REF_STATUS_NONE) {
|
if ((*ref)->status != REF_STATUS_NONE) {
|
||||||
/*
|
/*
|
||||||
@ -805,7 +851,12 @@ static int push_update_ref_status(struct strbuf *buf,
|
|||||||
|
|
||||||
(*ref)->status = status;
|
(*ref)->status = status;
|
||||||
(*ref)->forced_update |= forced;
|
(*ref)->forced_update |= forced;
|
||||||
(*ref)->remote_status = msg;
|
if (msg) {
|
||||||
|
if (status == REF_STATUS_OK)
|
||||||
|
(*ref)->report.message = msg;
|
||||||
|
else
|
||||||
|
(*ref)->report.error_message = msg;
|
||||||
|
}
|
||||||
return !(status == REF_STATUS_OK);
|
return !(status == REF_STATUS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
161
transport.c
161
transport.c
@ -436,37 +436,65 @@ int transport_refs_pushed(struct ref *ref)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int verbose)
|
static void update_tracking_ref(struct remote *remote, char *refname,
|
||||||
|
struct object_id *new_oid, int deletion,
|
||||||
|
int verbose)
|
||||||
{
|
{
|
||||||
struct refspec_item rs;
|
struct refspec_item rs;
|
||||||
|
|
||||||
if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
|
rs.src = refname;
|
||||||
return;
|
|
||||||
|
|
||||||
rs.src = ref->name;
|
|
||||||
rs.dst = NULL;
|
rs.dst = NULL;
|
||||||
|
|
||||||
if (!remote_find_tracking(remote, &rs)) {
|
if (!remote_find_tracking(remote, &rs)) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
|
fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
|
||||||
if (ref->deletion) {
|
if (deletion)
|
||||||
delete_ref(NULL, rs.dst, NULL, 0);
|
delete_ref(NULL, rs.dst, NULL, 0);
|
||||||
} else
|
else
|
||||||
update_ref("update by push", rs.dst, &ref->new_oid,
|
update_ref("update by push", rs.dst, new_oid,
|
||||||
NULL, 0, 0);
|
NULL, 0, 0);
|
||||||
free(rs.dst);
|
free(rs.dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int verbose)
|
||||||
|
{
|
||||||
|
char *refname;
|
||||||
|
struct object_id *new_oid;
|
||||||
|
struct ref_push_report_options *options;
|
||||||
|
|
||||||
|
if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
options = ref->report.options;
|
||||||
|
if (!options)
|
||||||
|
update_tracking_ref(remote, ref->name, &ref->new_oid,
|
||||||
|
ref->deletion, verbose);
|
||||||
|
else
|
||||||
|
for (; options; options = options->next) {
|
||||||
|
refname = options->ref_name ? (char *)options->ref_name : ref->name;
|
||||||
|
new_oid = options->new_oid ? options->new_oid : &ref->new_oid;
|
||||||
|
update_tracking_ref(remote, refname, new_oid,
|
||||||
|
is_null_oid(new_oid), verbose);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void print_ref_status(char flag, const char *summary,
|
static void print_ref_status(char flag, const char *summary,
|
||||||
struct ref *to, struct ref *from, const char *msg,
|
struct ref *to, struct ref *from, const char *msg,
|
||||||
|
struct ref_push_report_options *options,
|
||||||
int porcelain, int summary_width)
|
int porcelain, int summary_width)
|
||||||
{
|
{
|
||||||
|
const char *to_name;
|
||||||
|
|
||||||
|
if (options && options->ref_name)
|
||||||
|
to_name = options->ref_name;
|
||||||
|
else
|
||||||
|
to_name = to->name;
|
||||||
|
|
||||||
if (porcelain) {
|
if (porcelain) {
|
||||||
if (from)
|
if (from)
|
||||||
fprintf(stdout, "%c\t%s:%s\t", flag, from->name, to->name);
|
fprintf(stdout, "%c\t%s:%s\t", flag, from->name, to_name);
|
||||||
else
|
else
|
||||||
fprintf(stdout, "%c\t:%s\t", flag, to->name);
|
fprintf(stdout, "%c\t:%s\t", flag, to_name);
|
||||||
if (msg)
|
if (msg)
|
||||||
fprintf(stdout, "%s (%s)\n", summary, msg);
|
fprintf(stdout, "%s (%s)\n", summary, msg);
|
||||||
else
|
else
|
||||||
@ -480,9 +508,11 @@ static void print_ref_status(char flag, const char *summary,
|
|||||||
fprintf(stderr, " %s%c %-*s%s ", red, flag, summary_width,
|
fprintf(stderr, " %s%c %-*s%s ", red, flag, summary_width,
|
||||||
summary, reset);
|
summary, reset);
|
||||||
if (from)
|
if (from)
|
||||||
fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name));
|
fprintf(stderr, "%s -> %s",
|
||||||
|
prettify_refname(from->name),
|
||||||
|
prettify_refname(to_name));
|
||||||
else
|
else
|
||||||
fputs(prettify_refname(to->name), stderr);
|
fputs(prettify_refname(to_name), stderr);
|
||||||
if (msg) {
|
if (msg) {
|
||||||
fputs(" (", stderr);
|
fputs(" (", stderr);
|
||||||
fputs(msg, stderr);
|
fputs(msg, stderr);
|
||||||
@ -492,24 +522,52 @@ static void print_ref_status(char flag, const char *summary,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_ok_ref_status(struct ref *ref, int porcelain, int summary_width)
|
static void print_ok_ref_status(struct ref *ref,
|
||||||
|
struct ref_push_report_options *options,
|
||||||
|
int porcelain, int summary_width)
|
||||||
{
|
{
|
||||||
|
struct object_id *old_oid;
|
||||||
|
struct object_id *new_oid;
|
||||||
|
const char *ref_name;
|
||||||
|
int forced_update;
|
||||||
|
|
||||||
|
if (options && options->old_oid)
|
||||||
|
old_oid = options->old_oid;
|
||||||
|
else
|
||||||
|
old_oid = &ref->old_oid;
|
||||||
|
if (options && options->new_oid)
|
||||||
|
new_oid = options->new_oid;
|
||||||
|
else
|
||||||
|
new_oid = &ref->new_oid;
|
||||||
|
if (options && options->forced_update)
|
||||||
|
forced_update = options->forced_update;
|
||||||
|
else
|
||||||
|
forced_update = ref->forced_update;
|
||||||
|
if (options && options->ref_name)
|
||||||
|
ref_name = options->ref_name;
|
||||||
|
else
|
||||||
|
ref_name = ref->name;
|
||||||
|
|
||||||
if (ref->deletion)
|
if (ref->deletion)
|
||||||
print_ref_status('-', "[deleted]", ref, NULL, NULL,
|
print_ref_status('-', "[deleted]", ref, NULL, NULL,
|
||||||
porcelain, summary_width);
|
options, porcelain, summary_width);
|
||||||
else if (is_null_oid(&ref->old_oid))
|
else if (is_null_oid(old_oid))
|
||||||
print_ref_status('*',
|
print_ref_status('*',
|
||||||
(starts_with(ref->name, "refs/tags/") ? "[new tag]" :
|
(starts_with(ref_name, "refs/tags/")
|
||||||
"[new branch]"),
|
? "[new tag]"
|
||||||
ref, ref->peer_ref, NULL, porcelain, summary_width);
|
: (starts_with(ref_name, "refs/heads/")
|
||||||
|
? "[new branch]"
|
||||||
|
: "[new reference]")),
|
||||||
|
ref, ref->peer_ref, NULL,
|
||||||
|
options, porcelain, summary_width);
|
||||||
else {
|
else {
|
||||||
struct strbuf quickref = STRBUF_INIT;
|
struct strbuf quickref = STRBUF_INIT;
|
||||||
char type;
|
char type;
|
||||||
const char *msg;
|
const char *msg;
|
||||||
|
|
||||||
strbuf_add_unique_abbrev(&quickref, &ref->old_oid,
|
strbuf_add_unique_abbrev(&quickref, old_oid,
|
||||||
DEFAULT_ABBREV);
|
DEFAULT_ABBREV);
|
||||||
if (ref->forced_update) {
|
if (forced_update) {
|
||||||
strbuf_addstr(&quickref, "...");
|
strbuf_addstr(&quickref, "...");
|
||||||
type = '+';
|
type = '+';
|
||||||
msg = "forced update";
|
msg = "forced update";
|
||||||
@ -518,17 +576,18 @@ static void print_ok_ref_status(struct ref *ref, int porcelain, int summary_widt
|
|||||||
type = ' ';
|
type = ' ';
|
||||||
msg = NULL;
|
msg = NULL;
|
||||||
}
|
}
|
||||||
strbuf_add_unique_abbrev(&quickref, &ref->new_oid,
|
strbuf_add_unique_abbrev(&quickref, new_oid,
|
||||||
DEFAULT_ABBREV);
|
DEFAULT_ABBREV);
|
||||||
|
|
||||||
print_ref_status(type, quickref.buf, ref, ref->peer_ref, msg,
|
print_ref_status(type, quickref.buf, ref, ref->peer_ref, msg,
|
||||||
porcelain, summary_width);
|
options, porcelain, summary_width);
|
||||||
strbuf_release(&quickref);
|
strbuf_release(&quickref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int print_one_push_status(struct ref *ref, const char *dest, int count,
|
static int _print_one_push_status(struct ref *ref, const char *dest, int count,
|
||||||
int porcelain, int summary_width)
|
struct ref_push_report_options *options,
|
||||||
|
int porcelain, int summary_width)
|
||||||
{
|
{
|
||||||
if (!count) {
|
if (!count) {
|
||||||
char *url = transport_anonymize_url(dest);
|
char *url = transport_anonymize_url(dest);
|
||||||
@ -539,65 +598,89 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count,
|
|||||||
switch(ref->status) {
|
switch(ref->status) {
|
||||||
case REF_STATUS_NONE:
|
case REF_STATUS_NONE:
|
||||||
print_ref_status('X', "[no match]", ref, NULL, NULL,
|
print_ref_status('X', "[no match]", ref, NULL, NULL,
|
||||||
porcelain, summary_width);
|
options, porcelain, summary_width);
|
||||||
break;
|
break;
|
||||||
case REF_STATUS_REJECT_NODELETE:
|
case REF_STATUS_REJECT_NODELETE:
|
||||||
print_ref_status('!', "[rejected]", ref, NULL,
|
print_ref_status('!', "[rejected]", ref, NULL,
|
||||||
"remote does not support deleting refs",
|
"remote does not support deleting refs",
|
||||||
porcelain, summary_width);
|
options, porcelain, summary_width);
|
||||||
break;
|
break;
|
||||||
case REF_STATUS_UPTODATE:
|
case REF_STATUS_UPTODATE:
|
||||||
print_ref_status('=', "[up to date]", ref,
|
print_ref_status('=', "[up to date]", ref,
|
||||||
ref->peer_ref, NULL, porcelain, summary_width);
|
ref->peer_ref, NULL,
|
||||||
|
options, porcelain, summary_width);
|
||||||
break;
|
break;
|
||||||
case REF_STATUS_REJECT_NONFASTFORWARD:
|
case REF_STATUS_REJECT_NONFASTFORWARD:
|
||||||
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
||||||
"non-fast-forward", porcelain, summary_width);
|
"non-fast-forward",
|
||||||
|
options, porcelain, summary_width);
|
||||||
break;
|
break;
|
||||||
case REF_STATUS_REJECT_ALREADY_EXISTS:
|
case REF_STATUS_REJECT_ALREADY_EXISTS:
|
||||||
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
||||||
"already exists", porcelain, summary_width);
|
"already exists",
|
||||||
|
options, porcelain, summary_width);
|
||||||
break;
|
break;
|
||||||
case REF_STATUS_REJECT_FETCH_FIRST:
|
case REF_STATUS_REJECT_FETCH_FIRST:
|
||||||
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
||||||
"fetch first", porcelain, summary_width);
|
"fetch first",
|
||||||
|
options, porcelain, summary_width);
|
||||||
break;
|
break;
|
||||||
case REF_STATUS_REJECT_NEEDS_FORCE:
|
case REF_STATUS_REJECT_NEEDS_FORCE:
|
||||||
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
||||||
"needs force", porcelain, summary_width);
|
"needs force",
|
||||||
|
options, porcelain, summary_width);
|
||||||
break;
|
break;
|
||||||
case REF_STATUS_REJECT_STALE:
|
case REF_STATUS_REJECT_STALE:
|
||||||
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
||||||
"stale info", porcelain, summary_width);
|
"stale info",
|
||||||
|
options, porcelain, summary_width);
|
||||||
break;
|
break;
|
||||||
case REF_STATUS_REJECT_SHALLOW:
|
case REF_STATUS_REJECT_SHALLOW:
|
||||||
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
||||||
"new shallow roots not allowed",
|
"new shallow roots not allowed",
|
||||||
porcelain, summary_width);
|
options, porcelain, summary_width);
|
||||||
break;
|
break;
|
||||||
case REF_STATUS_REMOTE_REJECT:
|
case REF_STATUS_REMOTE_REJECT:
|
||||||
print_ref_status('!', "[remote rejected]", ref,
|
print_ref_status('!', "[remote rejected]", ref,
|
||||||
ref->deletion ? NULL : ref->peer_ref,
|
ref->deletion ? NULL : ref->peer_ref,
|
||||||
ref->remote_status, porcelain, summary_width);
|
ref->report.error_message,
|
||||||
|
options, porcelain, summary_width);
|
||||||
break;
|
break;
|
||||||
case REF_STATUS_EXPECTING_REPORT:
|
case REF_STATUS_EXPECTING_REPORT:
|
||||||
print_ref_status('!', "[remote failure]", ref,
|
print_ref_status('!', "[remote failure]", ref,
|
||||||
ref->deletion ? NULL : ref->peer_ref,
|
ref->deletion ? NULL : ref->peer_ref,
|
||||||
"remote failed to report status",
|
"remote failed to report status",
|
||||||
porcelain, summary_width);
|
options, porcelain, summary_width);
|
||||||
break;
|
break;
|
||||||
case REF_STATUS_ATOMIC_PUSH_FAILED:
|
case REF_STATUS_ATOMIC_PUSH_FAILED:
|
||||||
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
||||||
"atomic push failed", porcelain, summary_width);
|
"atomic push failed",
|
||||||
|
options, porcelain, summary_width);
|
||||||
break;
|
break;
|
||||||
case REF_STATUS_OK:
|
case REF_STATUS_OK:
|
||||||
print_ok_ref_status(ref, porcelain, summary_width);
|
print_ok_ref_status(ref, options, porcelain, summary_width);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int print_one_push_status(struct ref *ref, const char *dest, int count,
|
||||||
|
int porcelain, int summary_width)
|
||||||
|
{
|
||||||
|
struct ref_push_report_options *options;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
if (!ref->report.options)
|
||||||
|
return _print_one_push_status(ref, dest, count,
|
||||||
|
NULL, porcelain, summary_width);
|
||||||
|
|
||||||
|
for (options = ref->report.options; options; options = options->next)
|
||||||
|
_print_one_push_status(ref, dest, count + n++,
|
||||||
|
options, porcelain, summary_width);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
static int measure_abbrev(const struct object_id *oid, int sofar)
|
static int measure_abbrev(const struct object_id *oid, int sofar)
|
||||||
{
|
{
|
||||||
char hex[GIT_MAX_HEXSZ + 1];
|
char hex[GIT_MAX_HEXSZ + 1];
|
||||||
|
Reference in New Issue
Block a user