Merge branch 'jx/proc-receive-hook'
"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 doc: add document for capability report-status-v2 New capability "report-status-v2" for git-push receive-pack: feed report options to post-receive 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:
commit
6c430a647c
@ -114,6 +114,28 @@ 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".
|
||||||
|
+
|
||||||
|
Optional modifiers can be provided in the beginning of the value to filter
|
||||||
|
commands for specific actions: create (a), modify (m), delete (d).
|
||||||
|
A `!` can be included in the modifiers to negate the reference prefix entry.
|
||||||
|
E.g.:
|
||||||
|
+
|
||||||
|
git config --system --add receive.procReceiveRefs ad:refs/heads
|
||||||
|
git config --system --add receive.procReceiveRefs !:refs/heads
|
||||||
|
|
||||||
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.
|
||||||
|
@ -335,6 +335,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 option directives.
|
||||||
|
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 leading "ok" 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,41 @@ 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"
|
||||||
----
|
----
|
||||||
|
|
||||||
|
The 'report-status-v2' capability 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
|
||||||
|
command-ok-v2 = command-ok
|
||||||
|
*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" directives 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
@ -720,6 +720,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;
|
||||||
@ -97,6 +98,17 @@ static int keepalive_in_sec = 5;
|
|||||||
|
|
||||||
static struct tmp_objdir *tmp_objdir;
|
static struct tmp_objdir *tmp_objdir;
|
||||||
|
|
||||||
|
static struct proc_receive_ref {
|
||||||
|
unsigned int want_add:1,
|
||||||
|
want_delete:1,
|
||||||
|
want_modify:1,
|
||||||
|
negative_ref:1;
|
||||||
|
char *ref_prefix;
|
||||||
|
struct proc_receive_ref *next;
|
||||||
|
} *proc_receive_ref;
|
||||||
|
|
||||||
|
static void proc_receive_ref_append(const char *prefix);
|
||||||
|
|
||||||
static enum deny_action parse_deny_action(const char *var, const char *value)
|
static enum deny_action parse_deny_action(const char *var, const char *value)
|
||||||
{
|
{
|
||||||
if (value) {
|
if (value) {
|
||||||
@ -229,6 +241,13 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcmp(var, "receive.procreceiverefs") == 0) {
|
||||||
|
if (!value)
|
||||||
|
return config_error_nonbool(var);
|
||||||
|
proc_receive_ref_append(value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return git_default_config(var, value, cb);
|
return git_default_config(var, value, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +259,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,17 +329,94 @@ 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;
|
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;
|
||||||
char ref_name[FLEX_ARRAY]; /* more */
|
char ref_name[FLEX_ARRAY]; /* more */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void proc_receive_ref_append(const char *prefix)
|
||||||
|
{
|
||||||
|
struct proc_receive_ref *ref_pattern;
|
||||||
|
char *p;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
ref_pattern = xcalloc(1, sizeof(struct proc_receive_ref));
|
||||||
|
p = strchr(prefix, ':');
|
||||||
|
if (p) {
|
||||||
|
while (prefix < p) {
|
||||||
|
if (*prefix == 'a')
|
||||||
|
ref_pattern->want_add = 1;
|
||||||
|
else if (*prefix == 'd')
|
||||||
|
ref_pattern->want_delete = 1;
|
||||||
|
else if (*prefix == 'm')
|
||||||
|
ref_pattern->want_modify = 1;
|
||||||
|
else if (*prefix == '!')
|
||||||
|
ref_pattern->negative_ref = 1;
|
||||||
|
prefix++;
|
||||||
|
}
|
||||||
|
prefix++;
|
||||||
|
} else {
|
||||||
|
ref_pattern->want_add = 1;
|
||||||
|
ref_pattern->want_delete = 1;
|
||||||
|
ref_pattern->want_modify = 1;
|
||||||
|
}
|
||||||
|
len = strlen(prefix);
|
||||||
|
while (len && prefix[len - 1] == '/')
|
||||||
|
len--;
|
||||||
|
ref_pattern->ref_prefix = xmemdupz(prefix, len);
|
||||||
|
if (!proc_receive_ref) {
|
||||||
|
proc_receive_ref = ref_pattern;
|
||||||
|
} else {
|
||||||
|
struct proc_receive_ref *end;
|
||||||
|
|
||||||
|
end = proc_receive_ref;
|
||||||
|
while (end->next)
|
||||||
|
end = end->next;
|
||||||
|
end->next = ref_pattern;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int proc_receive_ref_matches(struct command *cmd)
|
||||||
|
{
|
||||||
|
struct proc_receive_ref *p;
|
||||||
|
|
||||||
|
if (!proc_receive_ref)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (p = proc_receive_ref; p; p = p->next) {
|
||||||
|
const char *match = p->ref_prefix;
|
||||||
|
const char *remains;
|
||||||
|
|
||||||
|
if (!p->want_add && is_null_oid(&cmd->old_oid))
|
||||||
|
continue;
|
||||||
|
else if (!p->want_delete && is_null_oid(&cmd->new_oid))
|
||||||
|
continue;
|
||||||
|
else if (!p->want_modify &&
|
||||||
|
!is_null_oid(&cmd->old_oid) &&
|
||||||
|
!is_null_oid(&cmd->new_oid))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (skip_prefix(cmd->ref_name, match, &remains) &&
|
||||||
|
(!*remains || *remains == '/')) {
|
||||||
|
if (!p->negative_ref)
|
||||||
|
return 1;
|
||||||
|
} else if (p->negative_ref) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void rp_error(const char *err, ...) __attribute__((format (printf, 1, 2)));
|
static void rp_error(const char *err, ...) __attribute__((format (printf, 1, 2)));
|
||||||
static void rp_warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
|
static void rp_warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
|
||||||
|
|
||||||
@ -692,6 +788,7 @@ static void prepare_push_cert_sha1(struct child_process *proc)
|
|||||||
|
|
||||||
struct receive_hook_feed_state {
|
struct receive_hook_feed_state {
|
||||||
struct command *cmd;
|
struct command *cmd;
|
||||||
|
struct ref_push_report *report;
|
||||||
int skip_broken;
|
int skip_broken;
|
||||||
struct strbuf buf;
|
struct strbuf buf;
|
||||||
const struct string_list *push_options;
|
const struct string_list *push_options;
|
||||||
@ -779,11 +876,31 @@ static int feed_receive_hook(void *state_, const char **bufp, size_t *sizep)
|
|||||||
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 (!state->report)
|
||||||
oid_to_hex(&cmd->old_oid), oid_to_hex(&cmd->new_oid),
|
state->report = cmd->report;
|
||||||
cmd->ref_name);
|
if (state->report) {
|
||||||
state->cmd = cmd->next;
|
struct object_id *old_oid;
|
||||||
|
struct object_id *new_oid;
|
||||||
|
const char *ref_name;
|
||||||
|
|
||||||
|
old_oid = state->report->old_oid ? state->report->old_oid : &cmd->old_oid;
|
||||||
|
new_oid = state->report->new_oid ? state->report->new_oid : &cmd->new_oid;
|
||||||
|
ref_name = state->report->ref_name ? state->report->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);
|
||||||
|
state->report = state->report->next;
|
||||||
|
if (!state->report)
|
||||||
|
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;
|
||||||
@ -802,6 +919,7 @@ static int run_receive_hook(struct command *commands,
|
|||||||
strbuf_init(&state.buf, 0);
|
strbuf_init(&state.buf, 0);
|
||||||
state.cmd = commands;
|
state.cmd = commands;
|
||||||
state.skip_broken = skip_broken;
|
state.skip_broken = skip_broken;
|
||||||
|
state.report = NULL;
|
||||||
if (feed_receive_hook(&state, NULL, NULL))
|
if (feed_receive_hook(&state, NULL, NULL))
|
||||||
return 0;
|
return 0;
|
||||||
state.cmd = commands;
|
state.cmd = commands;
|
||||||
@ -840,6 +958,268 @@ static int run_update_hook(struct command *cmd)
|
|||||||
return finish_command(&proc);
|
return finish_command(&proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct command *find_command_by_refname(struct command *list,
|
||||||
|
const char *refname)
|
||||||
|
{
|
||||||
|
for (; list; list = list->next)
|
||||||
|
if (!strcmp(list->ref_name, refname))
|
||||||
|
return 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;
|
||||||
|
struct ref_push_report *report = NULL;
|
||||||
|
int new_report = 0;
|
||||||
|
int code = 0;
|
||||||
|
int once = 0;
|
||||||
|
|
||||||
|
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")) {
|
||||||
|
const char *key, *val;
|
||||||
|
|
||||||
|
if (!hint || !(report || new_report)) {
|
||||||
|
if (!once++)
|
||||||
|
strbuf_addstr(errmsg, "proc-receive reported 'option' without a matching 'ok/ng' directive\n");
|
||||||
|
code = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (new_report) {
|
||||||
|
if (!hint->report) {
|
||||||
|
hint->report = xcalloc(1, sizeof(struct ref_push_report));
|
||||||
|
report = hint->report;
|
||||||
|
} else {
|
||||||
|
report = hint->report;
|
||||||
|
while (report->next)
|
||||||
|
report = report->next;
|
||||||
|
report->next = xcalloc(1, sizeof(struct ref_push_report));
|
||||||
|
report = report->next;
|
||||||
|
}
|
||||||
|
new_report = 0;
|
||||||
|
}
|
||||||
|
key = p;
|
||||||
|
p = strchr(key, ' ');
|
||||||
|
if (p)
|
||||||
|
*p++ = '\0';
|
||||||
|
val = p;
|
||||||
|
if (!strcmp(key, "refname"))
|
||||||
|
report->ref_name = xstrdup_or_null(val);
|
||||||
|
else if (!strcmp(key, "old-oid") && val &&
|
||||||
|
!parse_oid_hex(val, &old_oid, &val))
|
||||||
|
report->old_oid = oiddup(&old_oid);
|
||||||
|
else if (!strcmp(key, "new-oid") && val &&
|
||||||
|
!parse_oid_hex(val, &new_oid, &val))
|
||||||
|
report->new_oid = oiddup(&new_oid);
|
||||||
|
else if (!strcmp(key, "forced-update"))
|
||||||
|
report->forced_update = 1;
|
||||||
|
else if (!strcmp(key, "fall-through"))
|
||||||
|
/* Fall through, let 'receive-pack' to execute it. */
|
||||||
|
hint->run_proc_receive = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
report = NULL;
|
||||||
|
new_report = 0;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
hint->run_proc_receive |= RUN_PROC_RECEIVE_RETURNED;
|
||||||
|
if (!strcmp(head, "ng")) {
|
||||||
|
if (p)
|
||||||
|
hint->error_string = xstrdup(p);
|
||||||
|
else
|
||||||
|
hint->error_string = "failed";
|
||||||
|
code = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
new_report = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cmd = commands; cmd; cmd = cmd->next)
|
||||||
|
if (cmd->run_proc_receive && !cmd->error_string &&
|
||||||
|
!(cmd->run_proc_receive & RUN_PROC_RECEIVE_RETURNED)) {
|
||||||
|
cmd->error_string = "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->error_string)
|
||||||
|
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"
|
||||||
@ -1415,7 +1795,7 @@ 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);
|
||||||
@ -1455,7 +1835,7 @@ 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->error_string = update(cmd, si);
|
||||||
@ -1491,6 +1871,7 @@ 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)
|
||||||
@ -1520,6 +1901,22 @@ 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_ref) {
|
||||||
|
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||||
|
if (!should_process_cmd(cmd))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (proc_receive_ref_matches(cmd)) {
|
||||||
|
cmd->run_proc_receive = RUN_PROC_RECEIVE_SCHEDULED;
|
||||||
|
run_proc_receive = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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->error_string)
|
||||||
@ -1546,6 +1943,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->error_string &&
|
||||||
|
!(cmd->run_proc_receive & RUN_PROC_RECEIVE_RETURNED) &&
|
||||||
|
(cmd->run_proc_receive || use_atomic))
|
||||||
|
cmd->error_string = "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 +2034,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"))
|
||||||
@ -1947,6 +2354,51 @@ static void report(struct command *commands, const char *unpack_status)
|
|||||||
strbuf_release(&buf);
|
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 *report;
|
||||||
|
|
||||||
|
packet_buf_write(&buf, "unpack %s\n",
|
||||||
|
unpack_status ? unpack_status : "ok");
|
||||||
|
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (cmd->error_string) {
|
||||||
|
packet_buf_write(&buf, "ng %s %s\n",
|
||||||
|
cmd->ref_name,
|
||||||
|
cmd->error_string);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
packet_buf_write(&buf, "ok %s\n",
|
||||||
|
cmd->ref_name);
|
||||||
|
for (report = cmd->report; report; report = report->next) {
|
||||||
|
if (count++ > 0)
|
||||||
|
packet_buf_write(&buf, "ok %s\n",
|
||||||
|
cmd->ref_name);
|
||||||
|
if (report->ref_name)
|
||||||
|
packet_buf_write(&buf, "option refname %s\n",
|
||||||
|
report->ref_name);
|
||||||
|
if (report->old_oid)
|
||||||
|
packet_buf_write(&buf, "option old-oid %s\n",
|
||||||
|
oid_to_hex(report->old_oid));
|
||||||
|
if (report->new_oid)
|
||||||
|
packet_buf_write(&buf, "option new-oid %s\n",
|
||||||
|
oid_to_hex(report->new_oid));
|
||||||
|
if (report->forced_update)
|
||||||
|
packet_buf_write(&buf, "option forced-update\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 int delete_only(struct command *commands)
|
static int delete_only(struct command *commands)
|
||||||
{
|
{
|
||||||
struct command *cmd;
|
struct command *cmd;
|
||||||
@ -2055,7 +2507,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);
|
||||||
|
@ -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 *report;
|
||||||
|
|
||||||
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:
|
||||||
@ -94,6 +96,23 @@ static void print_helper_status(struct ref *ref)
|
|||||||
}
|
}
|
||||||
strbuf_addch(&buf, '\n');
|
strbuf_addch(&buf, '\n');
|
||||||
|
|
||||||
|
if (ref->status == REF_STATUS_OK) {
|
||||||
|
for (report = ref->report; report; report = report->next) {
|
||||||
|
if (count++ > 0)
|
||||||
|
strbuf_addf(&buf, "ok %s\n", ref->name);
|
||||||
|
if (report->ref_name)
|
||||||
|
strbuf_addf(&buf, "option refname %s\n",
|
||||||
|
report->ref_name);
|
||||||
|
if (report->old_oid)
|
||||||
|
strbuf_addf(&buf, "option old-oid %s\n",
|
||||||
|
oid_to_hex(report->old_oid));
|
||||||
|
if (report->new_oid)
|
||||||
|
strbuf_addf(&buf, "option new-oid %s\n",
|
||||||
|
oid_to_hex(report->new_oid));
|
||||||
|
if (report->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);
|
||||||
|
9
remote.h
9
remote.h
@ -93,6 +93,14 @@ 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 {
|
||||||
|
const char *ref_name;
|
||||||
|
struct object_id *old_oid;
|
||||||
|
struct object_id *new_oid;
|
||||||
|
unsigned int forced_update:1;
|
||||||
|
struct ref_push_report *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct ref {
|
struct ref {
|
||||||
struct ref *next;
|
struct ref *next;
|
||||||
struct object_id old_oid;
|
struct object_id old_oid;
|
||||||
@ -140,6 +148,7 @@ struct ref {
|
|||||||
REF_STATUS_ATOMIC_PUSH_FAILED
|
REF_STATUS_ATOMIC_PUSH_FAILED
|
||||||
} status;
|
} status;
|
||||||
char *remote_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 */
|
||||||
};
|
};
|
||||||
|
101
send-pack.c
101
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;
|
||||||
|
struct ref_push_report *report = NULL;
|
||||||
|
int new_report = 0;
|
||||||
|
int once = 0;
|
||||||
|
|
||||||
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, ' ');
|
const char *key, *val;
|
||||||
if (msg)
|
|
||||||
*msg++ = '\0';
|
|
||||||
|
|
||||||
|
if (!hint || !(report || new_report)) {
|
||||||
|
if (!once++)
|
||||||
|
error("'option' without a matching 'ok/ng' directive");
|
||||||
|
ret = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (new_report) {
|
||||||
|
if (!hint->report) {
|
||||||
|
hint->report = xcalloc(1, sizeof(struct ref_push_report));
|
||||||
|
report = hint->report;
|
||||||
|
} else {
|
||||||
|
report = hint->report;
|
||||||
|
while (report->next)
|
||||||
|
report = report->next;
|
||||||
|
report->next = xcalloc(1, sizeof(struct ref_push_report));
|
||||||
|
report = report->next;
|
||||||
|
}
|
||||||
|
new_report = 0;
|
||||||
|
}
|
||||||
|
key = p;
|
||||||
|
p = strchr(key, ' ');
|
||||||
|
if (p)
|
||||||
|
*p++ = '\0';
|
||||||
|
val = p;
|
||||||
|
if (!strcmp(key, "refname"))
|
||||||
|
report->ref_name = xstrdup_or_null(val);
|
||||||
|
else if (!strcmp(key, "old-oid") && val &&
|
||||||
|
!parse_oid_hex(val, &old_oid, &val))
|
||||||
|
report->old_oid = oiddup(&old_oid);
|
||||||
|
else if (!strcmp(key, "new-oid") && val &&
|
||||||
|
!parse_oid_hex(val, &new_oid, &val))
|
||||||
|
report->new_oid = oiddup(&new_oid);
|
||||||
|
else if (!strcmp(key, "forced-update"))
|
||||||
|
report->forced_update = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
report = NULL;
|
||||||
|
new_report = 0;
|
||||||
|
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);
|
||||||
@ -180,22 +234,27 @@ static int receive_status(struct packet_reader *reader, struct ref *refs)
|
|||||||
hint = find_ref_by_name(refs, refname);
|
hint = find_ref_by_name(refs, refname);
|
||||||
if (!hint) {
|
if (!hint) {
|
||||||
warning("remote reported status on unknown ref: %s",
|
warning("remote reported status on unknown ref: %s",
|
||||||
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->remote_status = xstrdup(p);
|
||||||
hint = hint->next;
|
else
|
||||||
|
hint->remote_status = "failed";
|
||||||
|
} else {
|
||||||
|
hint->status = REF_STATUS_OK;
|
||||||
|
hint->remote_status = xstrdup_or_null(p);
|
||||||
|
new_report = 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))
|
||||||
|
176
t/helper/test-proc-receive.c
Normal file
176
t/helper/test-proc-receive.c
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
#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;
|
||||||
|
static int die_readline;
|
||||||
|
static int no_push_options;
|
||||||
|
static int use_atomic;
|
||||||
|
static int use_push_options;
|
||||||
|
static int verbose;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
int nongit_ok = 0;
|
||||||
|
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()
|
||||||
|
};
|
||||||
|
|
||||||
|
setup_git_directory_gently(&nongit_ok);
|
||||||
|
|
||||||
|
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"
|
||||||
|
}
|
94
t/t5411/once-0010-report-status-v1.sh
Normal file
94
t/t5411/once-0010-report-status-v1.sh
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
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" '
|
||||||
|
{
|
||||||
|
if test -z "$GIT_DEFAULT_HASH" || test "$GIT_DEFAULT_HASH" = "sha1"
|
||||||
|
then
|
||||||
|
printf "%s %s refs/heads/master\0report-status\n" \
|
||||||
|
$A $B | packetize
|
||||||
|
else
|
||||||
|
printf "%s %s refs/heads/master\0report-status object-format=$GIT_DEFAULT_HASH\n" \
|
||||||
|
$A $B | packetize
|
||||||
|
fi &&
|
||||||
|
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
|
||||||
|
)
|
||||||
|
'
|
135
t/t5411/test-0050-proc-receive-refs-with-modifiers.sh
Normal file
135
t/t5411/test-0050-proc-receive-refs-with-modifiers.sh
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
test_expect_success "config receive.procReceiveRefs with modifiers ($PROTOCOL)" '
|
||||||
|
(
|
||||||
|
cd "$upstream" &&
|
||||||
|
git config --unset-all receive.procReceiveRefs &&
|
||||||
|
git config --add receive.procReceiveRefs m:refs/heads/master &&
|
||||||
|
git config --add receive.procReceiveRefs ad:refs/heads &&
|
||||||
|
git config --add receive.procReceiveRefs "a!:refs/heads"
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
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 refname refs/pull/123/head" \
|
||||||
|
-r "option old-oid $A" \
|
||||||
|
-r "option new-oid $B" \
|
||||||
|
-r "ok refs/tags/v123 " \
|
||||||
|
-r "option refname refs/pull/124/head"
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
|
||||||
|
# Refs of upstream : master(A)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
# git push : master(B) tags/v123
|
||||||
|
test_expect_success "proc-receive: update branch and new tag ($PROTOCOL)" '
|
||||||
|
git -C workbench push origin \
|
||||||
|
$B:refs/heads/master \
|
||||||
|
v123 >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> <TAG-v123> refs/tags/v123
|
||||||
|
remote: # proc-receive hook
|
||||||
|
remote: proc-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||||
|
remote: proc-receive< <ZERO-OID> <TAG-v123> refs/tags/v123
|
||||||
|
remote: proc-receive> ok refs/heads/master
|
||||||
|
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/tags/v123
|
||||||
|
remote: proc-receive> option refname refs/pull/124/head
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/pull/123/head
|
||||||
|
remote: post-receive< <ZERO-OID> <TAG-v123> refs/pull/124/head
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
<OID-A>..<OID-B> <COMMIT-B> -> refs/pull/123/head
|
||||||
|
* [new reference] v123 -> refs/pull/124/head
|
||||||
|
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
|
||||||
|
'
|
||||||
|
|
||||||
|
# Refs of upstream : master(A)
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
test_expect_success "setup upstream: create tags/v123 ($PROTOCOL)" '
|
||||||
|
git -C "$upstream" update-ref refs/heads/topic $A &&
|
||||||
|
git -C "$upstream" update-ref refs/tags/v123 $TAG &&
|
||||||
|
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/topic
|
||||||
|
<TAG-v123> refs/tags/v123
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
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 refname refs/pull/123/head" \
|
||||||
|
-r "option old-oid $A" \
|
||||||
|
-r "option new-oid $ZERO_OID" \
|
||||||
|
-r "ok refs/heads/next" \
|
||||||
|
-r "option refname refs/pull/124/head" \
|
||||||
|
-r "option new-oid $A"
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
|
||||||
|
# Refs of upstream : master(A) topic(A) tags/v123
|
||||||
|
# Refs of workbench: master(A) tags/v123
|
||||||
|
# git push : NULL topic(B) NULL next(A)
|
||||||
|
test_expect_success "proc-receive: create/delete branch, and delete tag ($PROTOCOL)" '
|
||||||
|
git -C workbench push origin \
|
||||||
|
:refs/heads/master \
|
||||||
|
$B:refs/heads/topic \
|
||||||
|
$A:refs/heads/next \
|
||||||
|
:refs/tags/v123 >out 2>&1 &&
|
||||||
|
make_user_friendly_and_stable_output <out >actual &&
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
remote: # pre-receive hook
|
||||||
|
remote: pre-receive< <COMMIT-A> <ZERO-OID> refs/heads/master
|
||||||
|
remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/topic
|
||||||
|
remote: pre-receive< <TAG-v123> <ZERO-OID> refs/tags/v123
|
||||||
|
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||||
|
remote: # proc-receive hook
|
||||||
|
remote: proc-receive< <COMMIT-A> <ZERO-OID> refs/heads/master
|
||||||
|
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||||
|
remote: proc-receive> ok refs/heads/master
|
||||||
|
remote: proc-receive> option refname refs/pull/123/head
|
||||||
|
remote: proc-receive> option old-oid <COMMIT-A>
|
||||||
|
remote: proc-receive> option new-oid <ZERO-OID>
|
||||||
|
remote: proc-receive> ok refs/heads/next
|
||||||
|
remote: proc-receive> option refname refs/pull/124/head
|
||||||
|
remote: proc-receive> option new-oid <COMMIT-A>
|
||||||
|
remote: # post-receive hook
|
||||||
|
remote: post-receive< <COMMIT-A> <ZERO-OID> refs/pull/123/head
|
||||||
|
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/topic
|
||||||
|
remote: post-receive< <TAG-v123> <ZERO-OID> refs/tags/v123
|
||||||
|
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/124/head
|
||||||
|
To <URL/of/upstream.git>
|
||||||
|
- [deleted] refs/pull/123/head
|
||||||
|
<OID-A>..<OID-B> <COMMIT-B> -> topic
|
||||||
|
- [deleted] v123
|
||||||
|
* [new reference] <COMMIT-A> -> refs/pull/124/head
|
||||||
|
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-B> refs/heads/topic
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
@ -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 &&
|
||||||
(
|
(
|
||||||
|
@ -723,13 +723,61 @@ static int fetch(struct transport *transport,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct push_update_ref_state {
|
||||||
|
struct ref *hint;
|
||||||
|
struct ref_push_report *report;
|
||||||
|
int new_report;
|
||||||
|
};
|
||||||
|
|
||||||
static int push_update_ref_status(struct strbuf *buf,
|
static int push_update_ref_status(struct strbuf *buf,
|
||||||
struct ref **ref,
|
struct push_update_ref_state *state,
|
||||||
struct ref *remote_refs)
|
struct ref *remote_refs)
|
||||||
{
|
{
|
||||||
char *refname, *msg;
|
char *refname, *msg;
|
||||||
int status, forced = 0;
|
int status, forced = 0;
|
||||||
|
|
||||||
|
if (starts_with(buf->buf, "option ")) {
|
||||||
|
struct object_id old_oid, new_oid;
|
||||||
|
const char *key, *val;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (!state->hint || !(state->report || state->new_report))
|
||||||
|
die(_("'option' without a matching 'ok/error' directive"));
|
||||||
|
if (state->new_report) {
|
||||||
|
if (!state->hint->report) {
|
||||||
|
state->hint->report = xcalloc(1, sizeof(struct ref_push_report));
|
||||||
|
state->report = state->hint->report;
|
||||||
|
} else {
|
||||||
|
state->report = state->hint->report;
|
||||||
|
while (state->report->next)
|
||||||
|
state->report = state->report->next;
|
||||||
|
state->report->next = xcalloc(1, sizeof(struct ref_push_report));
|
||||||
|
state->report = state->report->next;
|
||||||
|
}
|
||||||
|
state->new_report = 0;
|
||||||
|
}
|
||||||
|
key = buf->buf + 7;
|
||||||
|
p = strchr(key, ' ');
|
||||||
|
if (p)
|
||||||
|
*p++ = '\0';
|
||||||
|
val = p;
|
||||||
|
if (!strcmp(key, "refname"))
|
||||||
|
state->report->ref_name = xstrdup_or_null(val);
|
||||||
|
else if (!strcmp(key, "old-oid") && val &&
|
||||||
|
!parse_oid_hex(val, &old_oid, &val))
|
||||||
|
state->report->old_oid = oiddup(&old_oid);
|
||||||
|
else if (!strcmp(key, "new-oid") && val &&
|
||||||
|
!parse_oid_hex(val, &new_oid, &val))
|
||||||
|
state->report->new_oid = oiddup(&new_oid);
|
||||||
|
else if (!strcmp(key, "forced-update"))
|
||||||
|
state->report->forced_update = 1;
|
||||||
|
/* Not update remote namespace again. */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->report = NULL;
|
||||||
|
state->new_report = 0;
|
||||||
|
|
||||||
if (starts_with(buf->buf, "ok ")) {
|
if (starts_with(buf->buf, "ok ")) {
|
||||||
status = REF_STATUS_OK;
|
status = REF_STATUS_OK;
|
||||||
refname = buf->buf + 3;
|
refname = buf->buf + 3;
|
||||||
@ -785,16 +833,16 @@ static int push_update_ref_status(struct strbuf *buf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*ref)
|
if (state->hint)
|
||||||
*ref = find_ref_by_name(*ref, refname);
|
state->hint = find_ref_by_name(state->hint, refname);
|
||||||
if (!*ref)
|
if (!state->hint)
|
||||||
*ref = find_ref_by_name(remote_refs, refname);
|
state->hint = find_ref_by_name(remote_refs, refname);
|
||||||
if (!*ref) {
|
if (!state->hint) {
|
||||||
warning(_("helper reported unexpected status of %s"), refname);
|
warning(_("helper reported unexpected status of %s"), refname);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*ref)->status != REF_STATUS_NONE) {
|
if (state->hint->status != REF_STATUS_NONE) {
|
||||||
/*
|
/*
|
||||||
* Earlier, the ref was marked not to be pushed, so ignore the ref
|
* Earlier, the ref was marked not to be pushed, so ignore the ref
|
||||||
* status reported by the remote helper if the latter is 'no match'.
|
* status reported by the remote helper if the latter is 'no match'.
|
||||||
@ -803,9 +851,11 @@ static int push_update_ref_status(struct strbuf *buf,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*ref)->status = status;
|
if (status == REF_STATUS_OK)
|
||||||
(*ref)->forced_update |= forced;
|
state->new_report = 1;
|
||||||
(*ref)->remote_status = msg;
|
state->hint->status = status;
|
||||||
|
state->hint->forced_update |= forced;
|
||||||
|
state->hint->remote_status = msg;
|
||||||
return !(status == REF_STATUS_OK);
|
return !(status == REF_STATUS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -813,37 +863,57 @@ static int push_update_refs_status(struct helper_data *data,
|
|||||||
struct ref *remote_refs,
|
struct ref *remote_refs,
|
||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
|
struct ref *ref;
|
||||||
|
struct ref_push_report *report;
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
struct ref *ref = remote_refs;
|
struct push_update_ref_state state = { remote_refs, NULL, 0 };
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char *private;
|
|
||||||
|
|
||||||
if (recvline(data, &buf)) {
|
if (recvline(data, &buf)) {
|
||||||
ret = 1;
|
strbuf_release(&buf);
|
||||||
break;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buf.len)
|
if (!buf.len)
|
||||||
break;
|
break;
|
||||||
|
push_update_ref_status(&buf, &state, remote_refs);
|
||||||
if (push_update_ref_status(&buf, &ref, remote_refs))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (flags & TRANSPORT_PUSH_DRY_RUN || !data->rs.nr || data->no_private_update)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* propagate back the update to the remote namespace */
|
|
||||||
private = apply_refspecs(&data->rs, ref->name);
|
|
||||||
if (!private)
|
|
||||||
continue;
|
|
||||||
update_ref("update by helper", private, &ref->new_oid, NULL,
|
|
||||||
0, 0);
|
|
||||||
free(private);
|
|
||||||
}
|
}
|
||||||
strbuf_release(&buf);
|
strbuf_release(&buf);
|
||||||
return ret;
|
|
||||||
|
if (flags & TRANSPORT_PUSH_DRY_RUN || !data->rs.nr || data->no_private_update)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* propagate back the update to the remote namespace */
|
||||||
|
for (ref = remote_refs; ref; ref = ref->next) {
|
||||||
|
char *private;
|
||||||
|
|
||||||
|
if (ref->status != REF_STATUS_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!ref->report) {
|
||||||
|
private = apply_refspecs(&data->rs, ref->name);
|
||||||
|
if (!private)
|
||||||
|
continue;
|
||||||
|
update_ref("update by helper", private, &(ref->new_oid),
|
||||||
|
NULL, 0, 0);
|
||||||
|
free(private);
|
||||||
|
} else {
|
||||||
|
for (report = ref->report; report; report = report->next) {
|
||||||
|
private = apply_refspecs(&data->rs,
|
||||||
|
report->ref_name
|
||||||
|
? report->ref_name
|
||||||
|
: ref->name);
|
||||||
|
if (!private)
|
||||||
|
continue;
|
||||||
|
update_ref("update by helper", private,
|
||||||
|
report->new_oid
|
||||||
|
? report->new_oid
|
||||||
|
: &(ref->new_oid),
|
||||||
|
NULL, 0, 0);
|
||||||
|
free(private);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_common_push_options(struct transport *transport,
|
static void set_common_push_options(struct transport *transport,
|
||||||
|
156
transport.c
156
transport.c
@ -432,38 +432,67 @@ 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_one_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)
|
|
||||||
return;
|
|
||||||
|
|
||||||
memset(&rs, 0, sizeof(rs));
|
memset(&rs, 0, sizeof(rs));
|
||||||
rs.src = ref->name;
|
rs.src = refname;
|
||||||
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 *report;
|
||||||
|
|
||||||
|
if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
report = ref->report;
|
||||||
|
if (!report)
|
||||||
|
update_one_tracking_ref(remote, ref->name, &ref->new_oid,
|
||||||
|
ref->deletion, verbose);
|
||||||
|
else
|
||||||
|
for (; report; report = report->next) {
|
||||||
|
refname = report->ref_name ? (char *)report->ref_name : ref->name;
|
||||||
|
new_oid = report->new_oid ? report->new_oid : &ref->new_oid;
|
||||||
|
update_one_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 *report,
|
||||||
int porcelain, int summary_width)
|
int porcelain, int summary_width)
|
||||||
{
|
{
|
||||||
|
const char *to_name;
|
||||||
|
|
||||||
|
if (report && report->ref_name)
|
||||||
|
to_name = report->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
|
||||||
@ -477,9 +506,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);
|
||||||
@ -489,24 +520,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 *report,
|
||||||
|
int porcelain, int summary_width)
|
||||||
{
|
{
|
||||||
|
struct object_id *old_oid;
|
||||||
|
struct object_id *new_oid;
|
||||||
|
const char *ref_name;
|
||||||
|
int forced_update;
|
||||||
|
|
||||||
|
if (report && report->old_oid)
|
||||||
|
old_oid = report->old_oid;
|
||||||
|
else
|
||||||
|
old_oid = &ref->old_oid;
|
||||||
|
if (report && report->new_oid)
|
||||||
|
new_oid = report->new_oid;
|
||||||
|
else
|
||||||
|
new_oid = &ref->new_oid;
|
||||||
|
if (report && report->forced_update)
|
||||||
|
forced_update = report->forced_update;
|
||||||
|
else
|
||||||
|
forced_update = ref->forced_update;
|
||||||
|
if (report && report->ref_name)
|
||||||
|
ref_name = report->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);
|
report, 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,
|
||||||
|
report, 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";
|
||||||
@ -515,16 +574,17 @@ 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);
|
report, 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_report(struct ref *ref, const char *dest, int count,
|
||||||
|
struct ref_push_report *report,
|
||||||
int porcelain, int summary_width)
|
int porcelain, int summary_width)
|
||||||
{
|
{
|
||||||
if (!count) {
|
if (!count) {
|
||||||
@ -536,65 +596,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);
|
report, 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);
|
report, 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,
|
||||||
|
report, 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",
|
||||||
|
report, 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",
|
||||||
|
report, 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",
|
||||||
|
report, 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",
|
||||||
|
report, 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",
|
||||||
|
report, 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);
|
report, 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->remote_status,
|
||||||
|
report, 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);
|
report, 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",
|
||||||
|
report, 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, report, 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 *report;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
if (!ref->report)
|
||||||
|
return print_one_push_report(ref, dest, count,
|
||||||
|
NULL, porcelain, summary_width);
|
||||||
|
|
||||||
|
for (report = ref->report; report; report = report->next)
|
||||||
|
print_one_push_report(ref, dest, count + n++,
|
||||||
|
report, 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];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user